From 3b8b0c85ed79e76d9f24f02c2b150445be579ef9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Lozier?= Date: Mon, 18 Apr 2022 20:15:20 -0400 Subject: [PATCH] Enable test_inheritance --- .../Runtime/Operations/InstanceOps.cs | 34 +- .../Cases/IronPythonCasesManifest.ini | 3 - Tests/test_inheritance.py | 704 +++++++++--------- 3 files changed, 372 insertions(+), 369 deletions(-) diff --git a/Src/IronPython/Runtime/Operations/InstanceOps.cs b/Src/IronPython/Runtime/Operations/InstanceOps.cs index c43923015..c72679a26 100644 --- a/Src/IronPython/Runtime/Operations/InstanceOps.cs +++ b/Src/IronPython/Runtime/Operations/InstanceOps.cs @@ -24,12 +24,12 @@ namespace IronPython.Runtime.Operations { /// InstanceOps contains methods that get added to CLS types depending on what /// methods and constructors they define. These have not been added directly to /// PythonType since they need to be added conditionally. - /// + /// /// Possibilities include: - /// + /// /// __new__, one of 3 __new__ sets can be added: /// DefaultNew - This is the __new__ used for a PythonType (list, dict, object, etc...) that - /// has only 1 default public constructor that takes no parameters. These types are + /// has only 1 default public constructor that takes no parameters. These types are /// mutable types, and __new__ returns a new instance of the type, and __init__ can be used /// to re-initialize the types. This __new__ allows an unlimited number of arguments to /// be passed if a non-default __init__ is also defined. @@ -37,22 +37,22 @@ namespace IronPython.Runtime.Operations { /// NonDefaultNew - This is used when a type has more than one constructor, or only has one /// that takes more than zero parameters. This __new__ does not allow an arbitrary # of /// extra arguments. - /// + /// /// DefaultNewCls - This is the default new used for CLS types that have only a single ctor - /// w/ an arbitray number of arguments. This constructor allows setting of properties + /// w/ an arbitrary number of arguments. This constructor allows setting of properties /// based upon an extra set of kw-args, e.g.: System.Windows.Forms.Button(Text='abc'). It /// is only used on non-Python types. - /// + /// /// __init__: /// For types that do not define __init__ we have an __init__ function that takes an /// unlimited number of arguments and does nothing. All types share the same reference /// to 1 instance of this. - /// + /// /// next: Defined when a type is an enumerator to expose the Python iter protocol. - /// - /// + /// + /// /// repr: Added for types that override ToString - /// + /// /// get: added for types that implement IDescriptor /// public static class InstanceOps { @@ -75,7 +75,7 @@ internal static BuiltinMethodDescriptor Init { return _Init; } } - + internal static BuiltinFunction New { get { @@ -129,7 +129,7 @@ public static object OverloadedNewBasic(CodeContext context, SiteLocalStorage kwargs\u00F8) { if (type\u00F8 == null) throw PythonOps.TypeError("__new__ expected type object, got {0}", PythonOps.Repr(context, DynamicHelpers.GetPythonType(type\u00F8))); - + return overloads\u00F8.Call(context, null, null, ArrayUtils.EmptyObjects, kwargs\u00F8); } @@ -213,7 +213,7 @@ public static object NextMethod(object self) { /// public static PythonList DynamicDir(CodeContext/*!*/ context, IDynamicMetaObjectProvider self) { PythonList res = new PythonList(self.GetMetaObject(Expression.Parameter(typeof(object))).GetDynamicMemberNames()); - + // add in the non-dynamic members from the dynamic objects base class. Type t = self.GetType(); while (typeof(IDynamicMetaObjectProvider).IsAssignableFrom(t)) { @@ -553,7 +553,7 @@ public static bool ComparableLessEqual(T x, [NotNull]T y) where T : IComparable { return x.CompareTo(y) <= 0; } - + [return: MaybeNotImplemented] public static object ComparableEquality([NotNull]T x, object y) where T : IComparable { @@ -653,7 +653,7 @@ public static object ComparableLessEqual(object y, [NotNull]T x) // operator direction is reversed return ScriptingRuntimeHelpers.BooleanToObject(x.CompareTo(y) >= 0); } - + #endregion /// @@ -672,7 +672,7 @@ public static void ExitMethod(IDisposable/*!*/ self, object exc_type, object exc [PropertyMethod, StaticExtensionMethod] public static PythonList/*!*/ Get__all__(CodeContext/*!*/ context) { - Debug.Assert(typeof(T).IsSealed && typeof(T).IsAbstract, "__all__ should only be produced for static members"); + Debug.Assert(typeof(T).IsSealed && typeof(T).IsAbstract, "__all__ should only be produced for static members"); PythonType pt = DynamicHelpers.GetPythonTypeFromType(typeof(T)); @@ -801,7 +801,7 @@ out deserializeNew Debug.Assert(res); return PythonTuple.MakeTuple( - deserializeNew, // function to call, clr.DeserializeNew + deserializeNew, // function to call, clr.DeserializeNew data, // data to pass to it - our type & the raw data from the .NET serializer null // state, unused ); diff --git a/Src/IronPythonTest/Cases/IronPythonCasesManifest.ini b/Src/IronPythonTest/Cases/IronPythonCasesManifest.ini index 6ad278c3c..3468fbfc1 100644 --- a/Src/IronPythonTest/Cases/IronPythonCasesManifest.ini +++ b/Src/IronPythonTest/Cases/IronPythonCasesManifest.ini @@ -42,9 +42,6 @@ NotParallelSafe=true # Creates/deletes temporary modules and directories with fi [IronPython.test_importpkg] Ignore=true -[IronPython.test_inheritance] -Ignore=true - [IronPython.test_interactive] Ignore=true Reason=Requires powershell diff --git a/Tests/test_inheritance.py b/Tests/test_inheritance.py index 71eb3d4e2..e9484f1fc 100644 --- a/Tests/test_inheritance.py +++ b/Tests/test_inheritance.py @@ -2,11 +2,10 @@ # The .NET Foundation licenses this file to you under the Apache 2.0 License. # See the LICENSE file in the project root for more information. -import sys +import types import unittest from iptest import IronPythonTestCase, is_cli, run_test, skipUnlessIronPython -from iptest.type_util import * from functools import reduce def add(x, y): return x + y @@ -29,9 +28,9 @@ def ReturnWidth(self): return self.Width def ReturnSize(self): return self.Size - + i = InheritedClass() - + self.assertEqual(i.Width, 0) self.assertEqual(i.Height, 0) self.assertEqual(i.Size.width, 0) @@ -40,10 +39,10 @@ def ReturnSize(self): self.assertEqual(i.ReturnWidth(), 0) self.assertEqual(i.ReturnSize().width, 0) self.assertEqual(i.ReturnSize().height, 0) - + i.Width = 1 i.Height = 2 - + self.assertEqual(i.Width, 1) self.assertEqual(i.Height, 2) self.assertEqual(i.Size.width, 1) @@ -52,11 +51,11 @@ def ReturnSize(self): self.assertEqual(i.ReturnWidth(), 1) self.assertEqual(i.ReturnSize().width, 1) self.assertEqual(i.ReturnSize().height, 2) - + s = MySize(3, 4) - + i.Size = s - + self.assertEqual(i.Width, 3) self.assertEqual(i.Height, 4) self.assertEqual(i.Size.width, 3) @@ -65,13 +64,13 @@ def ReturnSize(self): self.assertEqual(i.ReturnWidth(), 3) self.assertEqual(i.ReturnSize().width, 3) self.assertEqual(i.ReturnSize().height, 4) - + @skipUnlessIronPython() def test_cli_new_inheritance(self): """verifies that we do the right thing with new slot's (e.g. public int new Foo { get; })""" from IronPythonTest import NewClass, MySize - + class InheritedClass(NewClass): def ReturnHeight(self): return self.Height @@ -79,7 +78,7 @@ def ReturnWidth(self): return self.Width def ReturnSize(self): return self.Size - + for i in (InheritedClass(), NewClass()): self.assertEqual(i.Width, 1) self.assertEqual(i.Height, 1) @@ -90,10 +89,10 @@ def ReturnSize(self): self.assertEqual(i.ReturnWidth(), 1) self.assertEqual(i.ReturnSize().width, 1) self.assertEqual(i.ReturnSize().height, 1) - + i.Width = 1 i.Height = 2 - + self.assertEqual(i.Width, 3) self.assertEqual(i.Height, 5) self.assertEqual(i.Size.width, 2) @@ -103,87 +102,87 @@ def ReturnSize(self): self.assertEqual(i.ReturnWidth(), 3) self.assertEqual(i.ReturnSize().width, 2) self.assertEqual(i.ReturnSize().height, 3) - + s = MySize(3, 4) - + i.Size = s - + self.assertEqual(i.Width, 7) self.assertEqual(i.Height, 9) self.assertEqual(i.Size.width, 4) self.assertEqual(i.Size.height, 5) - + if not hasattr(i, 'ReturnHeight'): # BUGBUG: We need to enable this for the inherited case. Currently ReflectedTypeBUilder # is replacing the derived size w/ the base size. self.assertEqual(i.size.width, 3) self.assertEqual(i.size.height, 4) - + if hasattr(i, 'ReturnHeight'): self.assertEqual(i.ReturnHeight(), 9) self.assertEqual(i.ReturnWidth(), 7) self.assertEqual(i.ReturnSize().width, 4) self.assertEqual(i.ReturnSize().height, 5) - + @skipUnlessIronPython() def test_override_hierarchy(self): from IronPythonTest import CliVirtualStuff self.assertEqual(CliVirtualStuff().VirtualMethod(1), 10) - + # overridden in base, should get base value class D1(CliVirtualStuff): def VirtualMethod(self, x): return 23 class D2(D1): pass - + self.assertEqual(D2().VirtualMethod(1), 23) - + # multiple new-style classes class D3(CliVirtualStuff): def VirtualMethod(self, x): return 5 - + class D4(D1, D3): pass - + self.assertEqual(D4().VirtualMethod(1), 23) - + class D5(D3, D1): pass - + self.assertEqual(D5().VirtualMethod(1), 5) - + class D6(D1, D3): def VirtualMethod(self, x): return 3 - + self.assertEqual(D6().VirtualMethod(1), 3) - + class D7(D1, D3): def VirtualMethod(self, x): return 4 - + self.assertEqual(D7().VirtualMethod(1), 4) # old-style class mixed in class C1: def VirtualMethod(self, x): return 42 - + class D8(C1, D2): pass - + # old-style comes first, it should take precedence self.assertEqual(D8().VirtualMethod(1), 42) - + class D9(D2, C1): pass - + # new-style comes first, it should take precedence self.assertEqual(D9().VirtualMethod(1), 23) - + class D10(C1, CliVirtualStuff): pass - + self.assertEqual(D10().VirtualMethod(1), 42) class D11(CliVirtualStuff, C1): pass - + self.assertEqual(D11().VirtualMethod(1), 10) @skipUnlessIronPython() @@ -191,15 +190,15 @@ def test_mbr_inheritance(self): import System class InheritFromMarshalByRefObject(System.MarshalByRefObject): pass - + @skipUnlessIronPython() def test_static_ctor_inheritance(self): from IronPythonTest import BaseClassStaticConstructor class StaticConstructorInherit(BaseClassStaticConstructor): pass - + sci = StaticConstructorInherit() - + self.assertEqual(sci.Value, 10) @skipUnlessIronPython() @@ -208,63 +207,63 @@ def test_cli_overriding(self): class PythonDerived(Overriding): def TemplateMethod(self): return "From Python" - + def BigTemplateMethod(self, *args): return ":".join(str(arg) for arg in args) - + def AbstractTemplateMethod(self): return "Overriden" - + o = PythonDerived() self.assertEqual(o.TopMethod(), "From Python - and Top") - + del PythonDerived.TemplateMethod self.assertEqual(o.TopMethod(), "From Base - and Top") - + def NewTemplateMethod(self): return "From Function" - + PythonDerived.TemplateMethod = NewTemplateMethod self.assertEqual(o.TopMethod(), "From Function - and Top") - + self.assertEqual(o.BigTopMethod(), "0:1:2:3:4:5:6:7:8:9 - and Top") - + del PythonDerived.BigTemplateMethod self.assertEqual(o.BigTopMethod(), "BaseBigTemplate - and Top") - - + + self.assertEqual(o.AbstractTopMethod(), "Overriden - and Top") del PythonDerived.AbstractTemplateMethod - + self.assertRaises(AttributeError, o.AbstractTopMethod) - + class PythonDerived2(PythonDerived): def TemplateMethod(self): return "Python2" - + o = PythonDerived2() self.assertEqual(o.TopMethod(), "Python2 - and Top") - - + + del PythonDerived2.TemplateMethod ##!!! TODO ##self.assertEqual(o.TopMethod(), "From Function - and Top") - + del PythonDerived.TemplateMethod self.assertEqual(o.TopMethod(), "From Base - and Top") - - + + self.assertEqual(o.BigTopMethod(), "BaseBigTemplate - and Top") - + @skipUnlessIronPython() def test_more_inheritance(self): from IronPythonTest import Inherited class CTest(Inherited): def TopMethod(self): return "CTest" - + o = CTest() - + @skipUnlessIronPython() def test_interface_inheritance(self): from IronPythonTest import ITestIt1, ITestIt2, TestIt @@ -272,17 +271,17 @@ class C(ITestIt1, ITestIt2): def Method(self, x=None): if x: return "Python"+repr(x) else: return "Python" - + o = C() self.assertEqual(TestIt.DoIt1(o), "Python") self.assertEqual(TestIt.DoIt2(o), "Python42") - + self.assertTrue(isinstance(o, ITestIt2)) self.assertTrue(issubclass(C, ITestIt2)) self.assertTrue(ITestIt2 in C.__bases__) - + # inheritance from a single interface should be verifable - + class SingleInherit(ITestIt1): pass @skipUnlessIronPython() @@ -291,11 +290,11 @@ def test_more_interface_inheritance(self): class Point(System.IFormattable): def __init__(self, x, y): self.x, self.y = x, y - + def ToString(self, format=None, fp=None): if format == 'x': return repr((self.x, self.y)) return "Point(%r, %r)" % (self.x, self.y) - + p = Point(1,2) self.assertEqual(p.ToString(), "Point(1, 2)") self.assertEqual(p.ToString('x', None), "(1, 2)") @@ -316,16 +315,16 @@ class MetaClass(type): def __new__(metacls, name, bases, vars): cls = type.__new__(metacls, name, bases, vars) return cls - + MC = MetaClass('Foo', (), {}) # vs CPython missing: ['__class__', '__delattr__', '__getattribute__', '__hash__', '__reduce__', '__reduce_ex__', '__setattr__', '__str__'] if is_cli: attrs = ['__dict__', '__doc__', '__init__', '__module__', '__new__', '__repr__', '__weakref__'] - + has = dir(MC) for attr in attrs: self.assertTrue(has.index(attr) != -1) - + # metaclass such as defined in string.py class MetaClass2(type): def __init__(metacls, name, bases, vars): @@ -351,7 +350,7 @@ def Test5(self, sc): return "xx" + str(sc) def Test6(self, x, sc): return "xx" + x + str(sc) - + a = OverrideParamTesting() x = a.CallTest1() self.assertEqual(x, 'xxaabb') @@ -363,30 +362,30 @@ def Test6(self, x, sc): self.assertEqual(x, 'xxOrdinal') x = a.CallTest6() self.assertEqual(x, 'xxaaOrdinal') - + try: a.CallTest3() self.assertTrue(False) except TypeError: pass - + try: a.CallTest4() self.assertTrue(False) except TypeError: pass - + def test_mangling(self): class _ToMangle(object): def getPriv(self): return self.__value def setPriv(self, val): self.__value = val - + class AccessMangled(_ToMangle): def inheritGetPriv(self): return self._ToMangle__value - + a = AccessMangled() a.setPriv('def') self.assertEqual(a.inheritGetPriv(), 'def') @@ -399,24 +398,24 @@ def test_even_more_overriding(self): class Test(BaseClass): def __new__(cls): return super(cls, Test).__new__(cls, Width=20, Height=30) - + a = Test() self.assertEqual(a.Width, 20) self.assertEqual(a.Height, 30) - + class Test(MoreOverridding): def Test1(self, *p): return "Override!" - + class OuterTest(Test): pass - + a = OuterTest() self.assertEqual(a.Test1(), "Override!") - + class OuterTest(Test): def Test1(self, *p): return "Override Outer!" - + a = OuterTest() self.assertEqual(a.Test1(), "Override Outer!") @@ -425,14 +424,16 @@ def test_oldstyle_inheritance_dir(self): class PythonBaseClass: def Func(self): print("PBC::Func") - + class PythonDerivedClass(PythonBaseClass): pass - + self.assertTrue('Func' in dir(PythonDerivedClass)) self.assertTrue('Func' in dir(PythonDerivedClass())) @skipUnlessIronPython() def test_cli_inheritance_dir(self): + import System + class PythonDerivedFromCLR(System.Collections.Generic.List[int]): pass # # now check that methods are available, but aren't visible in dir() @@ -440,81 +441,79 @@ class PythonDerivedFromCLR(System.Collections.Generic.List[int]): pass self.assertTrue('InsertRange' in dir(PythonDerivedFromCLR())) self.assertTrue(hasattr(PythonDerivedFromCLR, 'Capacity')) self.assertTrue(hasattr(PythonDerivedFromCLR(), 'InsertRange')) - # - @skipUnlessIronPython() def test_subclass_into_cli(self): """Subclassing once as python class, use it; and pass into CLI again""" from IronPythonTest import CliInterface, CliAbstractClass, UseCliClass - + class PythonClass(CliInterface): def M1(self): f.v = 100 def M2(self, x): f.v = 200 + x - + p = PythonClass() p.M1() self.assertEqual(f.v, 100) - + p.M2(1) self.assertEqual(f.v, 201) - + c = UseCliClass() c.AsParam10(p) self.assertEqual(f.v, 100) - + #Bug 562 #c.AsParam11(p, 2) #self.assertEqual(f.v, 202) - + p.InstanceAttr = 200 p2 = c.AsRetVal10(p) self.assertEqual(p, p2) self.assertEqual(p2.InstanceAttr, 200) - + # normal scenario class PythonClass(CliAbstractClass): def MV(self, x): f.v = 300 + x def MA(self, x): f.v = 400 + x - + p = PythonClass() p.MS(1) self.assertEqual(p.helperF, -2 * 1) - + p.MI(2) self.assertEqual(p.helperF, -3 * 2) - + p.MV(3) self.assertEqual(f.v, 303) - + p.MA(4) self.assertEqual(f.v, 404) - + c.AsParam20(p, 3) self.assertEqual(f.v, 303) - + c.AsParam21(p, 4) self.assertEqual(f.v, 404) - + c.AsParam22(p, 2) self.assertEqual(p.helperF, - 2*2) - + c.AsParam23(p, 1) self.assertEqual(p.helperF, - 3*1) - + # virtual function is not overriden in the python class: call locally, and pass back to clr and call. class PythonClass(CliAbstractClass): pass p = PythonClass() p.MV(5) self.assertEqual(p.helperF, -4 * 5) - + c.AsParam20(p, 6) self.assertEqual(p.helperF, -4 * 6) - + # "override" a non-virtual method, and pass the object back to clr. This method should not be called class PythonClass(CliAbstractClass): def MI(self, x): @@ -531,7 +530,7 @@ def test_subclass_twice(self): from IronPythonTest import CliInterface, CliAbstractClass class PythonClass(CliInterface): pass class PythonClass2(PythonClass): pass - + class PythonClass(CliAbstractClass): pass class PythonClass2(PythonClass): pass @@ -544,17 +543,17 @@ def test_negative_cli(self): class PythonClass(MySize): pass self.fail("should thrown") except TypeError: pass - + try: class PythonClass(DaysInt): pass self.fail("should thrown") except TypeError: pass - + try: class PythonClass(VoidDelegate): pass self.fail("should thrown") except TypeError: pass - + @skipUnlessIronPython() def test_all_virtuals(self): """All Virtual stuff can be overriden? and run""" @@ -568,23 +567,23 @@ def VirtualPropertyGetter(self): def VirtualPropertySetter(self, x): self.InstanceAttr = x VirtualProperty = property(VirtualPropertyGetter, VirtualPropertySetter) - + def VirtualProtectedMethod(self): return 2000 VirtualProtectedProperty = property(VirtualPropertyGetter, VirtualPropertySetter) - - + + p = PythonClass() self.assertEqual(p.VirtualMethod(1), 10) p.VirtualProperty = 99 self.assertEqual(p.VirtualProperty, 99) - + p2 = PythonClass2() self.assertEqual(p2.VirtualMethod(1), 20) p2.VirtualProperty = -1 self.assertEqual(p2.VirtualProperty, -20) - + self.assertTrue(p2.PublicStuffCheckHelper(-1 * 20,20 * 10)) - + p2.VirtualProtectedProperty = 999 self.assertTrue(p2.ProtectedStuffCheckHelper(999 * 20,2000)) @@ -611,17 +610,16 @@ def test_instance_override(self): from IronPythonTest import Overriding class Foo(Overriding): pass - + def MyTemplate(self): return "I'm Derived" - + a = Foo() - a.TemplateMethod = type(a.TemplateMethod)(MyTemplate, a) - - self.assertEqual(a.TopMethod(), "I'm Derived - and Top") + a.TemplateMethod = types.MethodType(MyTemplate, a) + self.assertEqual(a.TopMethod(), "I'm Derived - and Top") - @skipUnlessIronPython() + @unittest.skip("https://github.com/IronLanguages/ironpython3/issues/1413") # @skipUnlessIronPython() def test_new_init(self): """new / init combos w/ inheritance from CLR class""" from IronPythonTest import CtorTest @@ -642,115 +640,115 @@ class Foo(CtorTest): def __init__(self, a, b, c): checkEqual(self.CtorRan, 1) super(CtorTest, self).__init__(a, b, c) - + a = Foo("2","3","4") - - + + # single int, init adds extra args class Foo(CtorTest): def __init__(self, a): checkEqual(self.CtorRan, 3) super(CtorTest, self).__init__(a, 2, 3) - + a = Foo(2) - + # single string, init adds extra args - + class Foo(CtorTest): def __init__(self, a): checkEqual(self.CtorRan, 2) super(CtorTest, self).__init__(a, "2", "3") - + a = Foo("2") - - + + # single string (shoudl go to string overload) class Foo(CtorTest): def __init__(self): checkEqual(self.CtorRan, -1) super(CtorTest, self).__init__("2") - + a = Foo() - + # single int (should go to object overload) class Foo(CtorTest): def __init__(self): checkEqual(self.CtorRan, -1) super(CtorTest, self).__init__(2) - + a = Foo() - - + + # init adds int, we call w/ no args, should go to object class Foo(CtorTest): def __init__(self): checkEqual(self.CtorRan, -1) super(CtorTest, self).__init__(2) - - + + a = Foo() - + class Foo(CtorTest): def __init__(self): checkEqual(self.CtorRan, -1) super(CtorTest, self).__init__(2,3,4) - - + + a = Foo() - - + + ######################################################## # verify we can't call it w/ bad args... - + class Foo(CtorTest): def __init__(self): super(CtorTest, self).__init__() - + def BadFoo(): a = Foo(2,3,4,5) - + self.assertRaises(TypeError, BadFoo) - - + + ######################################################## # now run the __new__ tests. Overriding __new__ should # allow us to change the parameters that can be passed # to create the function - - + + class Foo(CtorTest): def __new__(cls, a, b, c): ret = CtorTest.__new__(CtorTest, a, b, c) return ret - + a = Foo(2,3,4) self.assertEqual(a.CtorRan, 0) - - + + a = Foo("2","3","4") self.assertEqual(a.CtorRan, 1) - + # use var-args to invoke arbitrary overloads... - + class Foo(CtorTest): def __new__(cls, *args): ret = CtorTest.__new__(CtorTest, *args) return ret - - + + a = Foo(2,3,4) self.assertEqual(a.CtorRan, 0) - + a = Foo("2","3","4") self.assertEqual(a.CtorRan, 1) - + a = Foo("abc") self.assertEqual(a.CtorRan, 2) - + a = Foo([]) self.assertEqual(a.CtorRan, 3) - - @skipUnlessIronPython() + + @unittest.skip("https://github.com/IronLanguages/ironpython3/issues/1413") # @skipUnlessIronPython() def test_new_init_combo(self): """new/init combo tests...""" from IronPythonTest import CtorTest @@ -759,54 +757,54 @@ def __new__(cls, *args): ret = CtorTest.__new__(CtorTest, *args) return ret def __init__(self, *args): pass - - + + # empty init, we should be able to create any of them... - + a = Foo(2,3,4) self.assertEqual(a.CtorRan, 0) - + a = Foo("2","3","4") self.assertEqual(a.CtorRan, 1) - + a = Foo("abc") self.assertEqual(a.CtorRan, 2) - + a = Foo([]) self.assertEqual(a.CtorRan, 3) - - + + class Foo(CtorTest): def __new__(cls, *args): ret = CtorTest.__new__(Foo, *args) return ret def __init__(self): super(CtorTest, self).__init__(self) - + #ok, we have a compatbile init... a = Foo() self.assertEqual(a.CtorRan, -1) - + #should all fail due to incompatible init. self.assertRaises(TypeError, Foo, 2,3,4) self.assertRaises(TypeError, Foo, "2","3","4") self.assertRaises(TypeError, Foo, "abc") self.assertRaises(TypeError, Foo, []) - - + + class Foo(CtorTest): def __new__(cls, *args): ret = CtorTest.__new__(Foo, *args) return ret def __init__(self, x): super(CtorTest, self).__init__(self, x) - - + + a = Foo("abc") self.assertEqual(a.CtorRan, 2) a = Foo([]) self.assertEqual(a.CtorRan, 3) - + self.assertRaises(TypeError, Foo) self.assertRaises(TypeError, Foo, 2, 3, 4) self.assertRaises(TypeError, Foo, "2", "3", "4") @@ -816,7 +814,7 @@ def test_tuple_inheritance(self): """verify tuple is ok after deriving from it.""" class T(tuple): pass - + result = 'a' in ('c','d','e') def test_str_inheritance(self): @@ -842,12 +840,12 @@ def test_conversions(self): """test converter logics and EmitCastFromObject""" import System from IronPythonTest import CReturnTypes, UseCReturnTypes, RtEnum - + ############################################# ## no inherited stuffs, expecting those default value defined in CReturnTypes - + class DReturnTypes(CReturnTypes): pass - + used = UseCReturnTypes(DReturnTypes()) used.Use_void() self.assertEqual(used.Use_Char(), System.Char.MaxValue) @@ -870,16 +868,16 @@ class DReturnTypes(CReturnTypes): pass self.assertEqual(used.Use_RtStruct().F, 1) self.assertEqual(used.Use_RtClass().F, 1) self.assertEqual(reduce(add, used.Use_IEnumerator()), 60) - + @skipUnlessIronPython() def test_inherit_returntypes(self): """inherited all, but with correct return types expect values defined here""" import System from IronPythonTest import CReturnTypes, UseCReturnTypes, RtEnum, RtStruct, RtClass - + def func(arg): return arg - + global flag flag = 10 class DReturnTypes(CReturnTypes): @@ -905,7 +903,7 @@ def M_RtDelegate(self): return func def M_RtStruct(self): return RtStruct(20) def M_RtClass(self): return RtClass(30) def M_IEnumerator(self): return iter([1, 2, 3, 4, 5]) - + used = UseCReturnTypes(DReturnTypes()) used.Use_void() self.assertEqual(flag, 20) @@ -931,7 +929,7 @@ def M_IEnumerator(self): return iter([1, 2, 3, 4, 5]) self.assertEqual(used.Use_RtClass().F, 30) self.assertEqual(list(used.Use_IEnumerator()), [1, 2, 3, 4, 5]) self.assertEqual(reduce(add, used.Use_IEnumerable()), 66) - + def create_class(self,retObj): if not is_cli: return None @@ -964,11 +962,11 @@ def M_IEnumerable(self): return retObj @skipUnlessIronPython() def test_inherited_returntypes_odd_returns(self): - """inherited all, but returns with a python old class, or new class, or with explicit ops""" + """inherited all, but returns with a python old class, or new class, or with explicit ops""" from IronPythonTest import UseCReturnTypes ## all return None DReturnTypes = self.create_class(None) - + used = UseCReturnTypes(DReturnTypes()) self.assertEqual(used.Use_Type(), None) self.assertEqual(used.Use_String(), None) @@ -976,23 +974,23 @@ def test_inherited_returntypes_odd_returns(self): self.assertEqual(used.Use_RtClass(), None) self.assertEqual(used.Use_Boolean(), False) self.assertEqual(used.Use_IEnumerator(), None) - + for f in [used.Use_Char, used.Use_Int32, used.Use_Int64, used.Use_Double, used.Use_Single, used.Use_Byte, used.Use_SByte, used.Use_RtEnum, used.Use_Int16, used.Use_UInt32, used.Use_UInt64, used.Use_UInt16, used.Use_RtStruct, ]: self.assertRaises(TypeError, f) - + ## return old class instance / user type instance class python_old_class: pass class python_new_class(object): pass - + def check_behavior(expected_obj): DReturnTypes = self.create_class(expected_obj) used = UseCReturnTypes(DReturnTypes()) - + self.assertEqual(used.Use_void(), None) self.assertEqual(used.Use_Boolean(), True) - + for f in [used.Use_Char, used.Use_Int32, used.Use_String, used.Use_Int64, used.Use_Double, used.Use_Single, used.Use_Byte, used.Use_SByte, used.Use_Int16, used.Use_UInt32, used.Use_UInt64, used.Use_UInt16, used.Use_Type, @@ -1000,7 +998,7 @@ def check_behavior(expected_obj): #used.Use_RtDelegate, ]: self.assertRaises(TypeError, f) - + check_behavior(python_old_class()) check_behavior(python_new_class()) @@ -1010,14 +1008,14 @@ def test_extensible_int(self): import System from IronPythonTest import UseCReturnTypes class python_my_int(int): pass - + def check_behavior(expected_obj): DReturnTypes = self.create_class(expected_obj) used = UseCReturnTypes(DReturnTypes()) - + self.assertEqual(used.Use_void(), None) self.assertEqual(used.Use_Boolean(), True) - + self.assertEqual(used.Use_Int32(), System.Int32.Parse("10")) self.assertEqual(used.Use_Int64(), System.Int64.Parse("10")) self.assertEqual(used.Use_Double(), System.Double.Parse("10")) @@ -1028,15 +1026,15 @@ def check_behavior(expected_obj): self.assertEqual(used.Use_SByte(), System.SByte.Parse("10")) self.assertEqual(used.Use_Int16(), System.Int16.Parse("10")) self.assertEqual(used.Use_UInt16(), System.UInt16.Parse("10")) - + for f in [used.Use_Char, used.Use_String, used.Use_Type, used.Use_RtEnum, used.Use_RtStruct, used.Use_RtClass, used.Use_IEnumerator # used.Use_RtDelegate, ]: self.assertRaises(TypeError, f) - + check_behavior(python_my_int(10)) - + @skipUnlessIronPython() def test_custom_number_conversion(self): """customized __int__. __float__""" @@ -1048,222 +1046,230 @@ def __float__(self): return 12345.6 class python_new_class(object): def __int__(self): return 100 def __float__(self): return 12345.6 - + def check_behavior(expected_obj): DReturnTypes = self.create_class(expected_obj) used = UseCReturnTypes(DReturnTypes()) - + self.assertEqual(used.Use_void(), None) self.assertEqual(used.Use_Boolean(), True) self.assertEqual(used.Use_Int32(), System.Int32.Parse("100")) self.assertEqual(used.Use_Double(), System.Double.Parse("12345.6", System.Globalization.CultureInfo.InvariantCulture)) - + for f in [used.Use_Int16, used.Use_UInt32, used.Use_UInt64, used.Use_UInt16, used.Use_Single, used.Use_Byte, used.Use_SByte, used.Use_Int64, used.Use_Char, used.Use_String, used.Use_Type, used.Use_RtEnum, used.Use_RtStruct, used.Use_RtClass, used.Use_IEnumerator #used.Use_RtDelegate, ]: self.assertRaises(TypeError, f) - + check_behavior(python_old_class()) check_behavior(python_new_class()) - @skipUnlessIronPython() + @unittest.skip("https://github.com/IronLanguages/ironpython3/issues/1413") # @skipUnlessIronPython() def test_return_interesting(self): """inherited all, but with more interesting return types""" + import System from IronPythonTest import CReturnTypes, UseCReturnTypes, RtClass - + class DReturnTypes(CReturnTypes): pass drt = DReturnTypes() used = UseCReturnTypes(drt) - + def func(self): global flag; flag = 60; return 70 DReturnTypes.M_void = func self.assertEqual(used.Use_void(), None) self.assertEqual(flag, 60) - + ## Char DReturnTypes.M_Char = lambda self: ord('z') self.assertRaises(TypeError, used.Use_Char) - + DReturnTypes.M_Char = lambda self: 'y' self.assertEqual(used.Use_Char(), System.Char.Parse('y')) - + DReturnTypes.M_Char = lambda self: '' self.assertRaises(TypeError, used.Use_Char) - + DReturnTypes.M_Char = lambda self: 'abc' self.assertRaises(TypeError, used.Use_Char) - + ## String DReturnTypes.M_String = lambda self: 'z' self.assertEqual(used.Use_String(), 'z') - + DReturnTypes.M_String = lambda self: '' self.assertEqual(used.Use_String(), System.String.Empty) - + DReturnTypes.M_String = lambda self: ord('z') self.assertRaises(TypeError, used.Use_String) - + ## Int32 DReturnTypes.M_Int32 = lambda self: System.Char.Parse('z') self.assertRaises(TypeError, used.Use_Int32) - + DReturnTypes.M_Int32 = lambda self: System.SByte.Parse('-123') self.assertEqual(used.Use_Int32(), -123) - + DReturnTypes.M_Int32 = lambda self: 12345678901234 self.assertRaises(OverflowError, used.Use_Int32) - + ## RtClass class MyRtClass(RtClass): def __init__(self, value): super(MyRtClass, self).__init__(value) - + DReturnTypes.M_RtClass = lambda self: MyRtClass(500) self.assertEqual(used.Use_RtClass().F, 500) - + ## IEnumerator DReturnTypes.M_IEnumerator = lambda self: iter((2, 20, 200, 2000)) self.assertEqual(tuple(used.Use_IEnumerator()), (2, 20, 200, 2000)) - + ## IEnumerable DReturnTypes.M_IEnumerable = lambda self: (2, 20, 200, 2000) self.assertEqual(reduce(add, used.Use_IEnumerable()), 2222) - + DReturnTypes.M_IEnumerator = lambda self: iter({ 1 : "one", 10: "two", 100: "three"}) self.assertEqual(set(used.Use_IEnumerator()), set([1, 10, 100])) - + DReturnTypes.M_IEnumerable = lambda self: { 1 : "one", 10: "two", 100: "three"} self.assertEqual(reduce(add, used.Use_IEnumerable()), 111) - + DReturnTypes.M_IEnumerator = lambda self: iter(System.Array[int](list(range(10)))) self.assertEqual(list(used.Use_IEnumerator()), list(range(10))) - + DReturnTypes.M_IEnumerable = lambda self: System.Array[int](list(range(10))) self.assertEqual(reduce(add, used.Use_IEnumerable()), 45) - + ## RtDelegate def func2(arg1, arg2): return arg1 * arg2 - + DReturnTypes.M_RtDelegate = lambda self : func2 delegate = used.Use_RtDelegate() self.assertRaises(TypeError, delegate, 1) - @skipUnlessIronPython() - def test_redefine_non_virtual(): - ############################################# - ## Redefine non-virtual method: - - class DReturnTypes(CReturnTypes): pass - - used = UseCReturnTypes(DReturnTypes()) - self.assertEqual(used.Use_NonVirtual(), 100) - - class DReturnTypes(CReturnTypes): - def M_NonVirtual(self): return 200 - - used = UseCReturnTypes(DReturnTypes()) - self.assertEqual(used.Use_NonVirtual(), 100) - - def test_interface_abstract_type(): - ############################################# - ## Similar but smaller set of test for interface/abstract Type - ## - def test_returntype(basetype, usetype): - class derived(basetype): pass - - used = usetype(derived()) - - for f in [ used.Use_void,used.Use_Char,used.Use_Int32,used.Use_String,used.Use_Int64,used.Use_Double,used.Use_Boolean, - used.Use_Single,used.Use_Byte,used.Use_SByte,used.Use_Int16,used.Use_UInt32,used.Use_UInt64,used.Use_UInt16, - used.Use_Type,used.Use_RtEnum,used.Use_RtDelegate,used.Use_RtStruct,used.Use_RtClass,used.Use_IEnumerator, - ]: - self.assertRaises(AttributeError, f) - - class derived(basetype): - def M_void(self): global flag; flag = 20 - def M_Char(self): return System.Char.MinValue - def M_Int32(self): return System.Int32.MinValue - def M_String(self): return "hello" - def M_Int64(self): return System.Int64.MinValue - def M_Double(self): return System.Double.MinValue - def M_Boolean(self): return False - def M_Single(self): return System.Single.MinValue - def M_Byte(self): return System.Byte.MinValue - def M_SByte(self): return System.SByte.MinValue - def M_Int16(self): return System.Int16.MinValue - def M_UInt32(self): return System.UInt32.MinValue - def M_UInt64(self): return System.UInt64.MinValue - def M_UInt16(self): return System.UInt16.MinValue - def M_Type(self): - return System.Type.GetType("System.Int64") - def M_RtEnum(self): return RtEnum.B - def M_RtDelegate(self): return lambda arg: arg * 5 - def M_RtStruct(self): return RtStruct(20) - def M_RtClass(self): return RtClass(30) - def M_IEnumerator(self): return iter([1, 2, 3, 4, 5]) - def M_IEnumerable(self): return [7, 8, 9, 10, 11] - - used = usetype(derived()) - used.Use_void() - self.assertEqual(flag, 20) - self.assertEqual(used.Use_Char(), System.Char.MinValue) - self.assertEqual(used.Use_Int32(), System.Int32.MinValue) - self.assertEqual(used.Use_String(), "hello") - self.assertEqual(used.Use_Int64(), System.Int64.MinValue) - self.assertEqual(used.Use_Double(), System.Double.MinValue) - self.assertEqual(used.Use_Boolean(), False) - self.assertEqual(used.Use_Single(), System.Single.MinValue) - self.assertEqual(used.Use_Byte(), System.Byte.MinValue) - self.assertEqual(used.Use_SByte(), System.SByte.MinValue) - self.assertEqual(used.Use_Int16(), System.Int16.MinValue) - self.assertEqual(used.Use_UInt32(), System.UInt32.MinValue) - self.assertEqual(used.Use_UInt64(), System.UInt64.MinValue) - self.assertEqual(used.Use_UInt16(), System.UInt16.MinValue) - self.assertEqual(used.Use_Type(), System.Type.GetType("System.Int64")) - self.assertEqual(used.Use_RtEnum(), RtEnum.B) - self.assertEqual(used.Use_RtDelegate().Invoke(100), 100 * 5) - self.assertEqual(used.Use_RtStruct().F, 20) - self.assertEqual(used.Use_RtClass().F, 30) - self.assertEqual(list(used.Use_IEnumerator()), [1, 2, 3, 4, 5]) - self.assertEqual(reduce(add, used.Use_IEnumerable()), 45) - - test_returntype(IReturnTypes, UseIReturnTypes) - test_returntype(AReturnTypes, UseAReturnTypes) - - - def test_bigvirtual_derived(): - # verify that classes w/ large vtables we get the - # correct method dispatch when overriding bases - class BigVirtualDerived(BigVirtualClass): - def __init__(self): - self.funcCalled = False - for x in range(50): - exec('def M%d(self):\n self.funcCalled = True\n return super(type(self), self).M%d()' % (x, x)) - - a = BigVirtualDerived() + @skipUnlessIronPython() + def test_redefine_non_virtual(self): + # Redefine non-virtual method: + + from IronPythonTest import CReturnTypes, UseCReturnTypes + + class DReturnTypes(CReturnTypes): pass + + used = UseCReturnTypes(DReturnTypes()) + self.assertEqual(used.Use_NonVirtual(), 100) + + class DReturnTypes(CReturnTypes): + def M_NonVirtual(self): return 200 + + used = UseCReturnTypes(DReturnTypes()) + self.assertEqual(used.Use_NonVirtual(), 100) + + @skipUnlessIronPython() + def test_interface_abstract_type(self): + # Similar but smaller set of test for interface/abstract Type + + import System + from IronPythonTest import RtEnum, RtStruct, RtClass, IReturnTypes, UseIReturnTypes, AReturnTypes, UseAReturnTypes + + def test_returntype(basetype, usetype): + class derived(basetype): pass + + used = usetype(derived()) + + for f in [ used.Use_void,used.Use_Char,used.Use_Int32,used.Use_String,used.Use_Int64,used.Use_Double,used.Use_Boolean, + used.Use_Single,used.Use_Byte,used.Use_SByte,used.Use_Int16,used.Use_UInt32,used.Use_UInt64,used.Use_UInt16, + used.Use_Type,used.Use_RtEnum,used.Use_RtDelegate,used.Use_RtStruct,used.Use_RtClass,used.Use_IEnumerator, + ]: + self.assertRaises(AttributeError, f) + + class derived(basetype): + def M_void(self): global flag; flag = 20 + def M_Char(self): return System.Char.MinValue + def M_Int32(self): return System.Int32.MinValue + def M_String(self): return "hello" + def M_Int64(self): return System.Int64.MinValue + def M_Double(self): return System.Double.MinValue + def M_Boolean(self): return False + def M_Single(self): return System.Single.MinValue + def M_Byte(self): return System.Byte.MinValue + def M_SByte(self): return System.SByte.MinValue + def M_Int16(self): return System.Int16.MinValue + def M_UInt32(self): return System.UInt32.MinValue + def M_UInt64(self): return System.UInt64.MinValue + def M_UInt16(self): return System.UInt16.MinValue + def M_Type(self): + return System.Type.GetType("System.Int64") + def M_RtEnum(self): return RtEnum.B + def M_RtDelegate(self): return lambda arg: arg * 5 + def M_RtStruct(self): return RtStruct(20) + def M_RtClass(self): return RtClass(30) + def M_IEnumerator(self): return iter([1, 2, 3, 4, 5]) + def M_IEnumerable(self): return [7, 8, 9, 10, 11] + + used = usetype(derived()) + used.Use_void() + self.assertEqual(flag, 20) + self.assertEqual(used.Use_Char(), System.Char.MinValue) + self.assertEqual(used.Use_Int32(), System.Int32.MinValue) + self.assertEqual(used.Use_String(), "hello") + self.assertEqual(used.Use_Int64(), System.Int64.MinValue) + self.assertEqual(used.Use_Double(), System.Double.MinValue) + self.assertEqual(used.Use_Boolean(), False) + self.assertEqual(used.Use_Single(), System.Single.MinValue) + self.assertEqual(used.Use_Byte(), System.Byte.MinValue) + self.assertEqual(used.Use_SByte(), System.SByte.MinValue) + self.assertEqual(used.Use_Int16(), System.Int16.MinValue) + self.assertEqual(used.Use_UInt32(), System.UInt32.MinValue) + self.assertEqual(used.Use_UInt64(), System.UInt64.MinValue) + self.assertEqual(used.Use_UInt16(), System.UInt16.MinValue) + self.assertEqual(used.Use_Type(), System.Type.GetType("System.Int64")) + self.assertEqual(used.Use_RtEnum(), RtEnum.B) + self.assertEqual(used.Use_RtDelegate().Invoke(100), 100 * 5) + self.assertEqual(used.Use_RtStruct().F, 20) + self.assertEqual(used.Use_RtClass().F, 30) + self.assertEqual(list(used.Use_IEnumerator()), [1, 2, 3, 4, 5]) + self.assertEqual(reduce(add, used.Use_IEnumerable()), 45) + + test_returntype(IReturnTypes, UseIReturnTypes) + test_returntype(AReturnTypes, UseAReturnTypes) + + @skipUnlessIronPython() + def test_bigvirtual_derived(self): + # verify that classes w/ large vtables we get the + # correct method dispatch when overriding bases + + from IronPythonTest import BigVirtualClass + + class BigVirtualDerived(BigVirtualClass): + def __init__(self): + self.funcCalled = False for x in range(50): - # call from Python - self.assertEqual(a.funcCalled, False) - self.assertEqual(x, getattr(a, 'M'+str(x))()) - self.assertEqual(a.funcCalled, True) - a.funcCalled = False - # call non-virtual method that calls from C# - self.assertEqual(x, getattr(a, 'CallM'+str(x))()) - self.assertEqual(a.funcCalled, True) - a.funcCalled = False - + exec('def M%d(self):\n self.funcCalled = True\n return super(type(self), self).M%d()' % (x, x)) + + a = BigVirtualDerived() + for x in range(50): + # call from Python + self.assertEqual(a.funcCalled, False) + self.assertEqual(x, getattr(a, 'M'+str(x))()) + self.assertEqual(a.funcCalled, True) + a.funcCalled = False + # call non-virtual method that calls from C# + self.assertEqual(x, getattr(a, 'CallM'+str(x))()) + self.assertEqual(a.funcCalled, True) + a.funcCalled = False + def test_super_inheritance(self): # descriptor for super should return derived class, not a new instance of super class foo(super): def __init__(self, *args): return super(foo, self).__init__(*args) - - + + class bar(object): pass - + # when lookup comes from super's class it should # be from it's type, not from the super base type self.assertEqual(foo(bar).__class__, foo) @@ -1272,7 +1278,7 @@ class bar(object): pass self.assertEqual(type(bar().x), foo) # once via . x = foo(bar) self.assertEqual(type(x.__get__(bar, foo) ), foo) # once by calling descriptor directly - + def test_super_new_init(self): x = super.__new__(super) self.assertEqual(x.__thisclass__, None) @@ -1280,17 +1286,17 @@ def test_super_new_init(self): self.assertEqual(x.__self_class__, None) x.__init__(super, None) - + self.assertEqual(x.__thisclass__, super) self.assertEqual(x.__self__, None) self.assertEqual(x.__self_class__, None) x.__init__(super, x) - + self.assertEqual(x.__thisclass__, super) self.assertEqual(x.__self__, x) self.assertEqual(x.__self_class__, super) - + self.assertTrue(repr(x.__self__).find('') != -1) # __self__'s repr goes recursive and gets it's display tweaked def test_super_class(self): @@ -1302,21 +1308,21 @@ class custDescr(object): def __get__(self, instance, owner): checkEqual(instance, None) return 'abc' - + class base(object): aProp = property(lambda self: 'foo') aDescr = custDescr() - + class sub(base): def test1(cls): return super(sub, cls).aProp def test2(cls): return super(sub, cls).aDescr test1 = classmethod(test1) test2 = classmethod(test2) - + self.assertEqual(sub.test2(), 'abc') self.assertEqual(type(sub.test1()), property) - - + + def test_super_proxy(self): def checkEqual(first,second): self.assertEqual(first,second) @@ -1327,28 +1333,28 @@ def __get__(self, instance, context): checkEqual(context, C) x = self.func.__get__(instance, context) return x - + class Proxy(object): def __init__(self, obj): self.__obj = obj def __getattribute__(self, name): if name.startswith("_Proxy__"): return object.__getattribute__(self, name) else: return getattr(self.__obj, name) - + class B(object): def f(self): return "B.f" - + class C(B): def f(self): return super(C, self).f() + "->C.f" - + C.f = mydescr(C.f) B.f = mydescr(B.f) obj = C() p = Proxy(obj) self.assertEqual(C.f(p), 'B.f->C.f') - + def test_super_tostringself(self): def check(condition): self.assertTrue(condition) @@ -1377,12 +1383,12 @@ def __init__(self): checkEqual(self.Bar, None) self.Bar = 23 checkEqual(self.Bar, 23) - + checkEqual(self.GetFoo(), 42) checkEqual(self.GetBar(), 23) - + a = MyClass() self.assertEqual(a.GetFoo(), 42) self.assertEqual(a.GetBar(), 23) -run_test(__name__); +run_test(__name__)