Hi, all,
I just tested it with C#, with different results:
Using the dynamic keyword, it seems that C# using “dynamic” does not honor the
optional parameter in any “inherited” case, it only works when the method
implementation also provides the default parameter. ☹
This closely matches the behavior of the “normal” C# compiler, which delivers
compiler errors in those cases – it works when I either have the interface or
ABC as type, or the method implementation also has the default parameter
declared. It also chooses the default value depending on the variable type.
Thus, it seems that C# is even more restrictive than IronPython right now, at
least when the “dynamic” keyword is used.
Just as a side note, we successfully worked around the problem in our use case,
so there is no urgent fix necessary, it was more some kind of curiosity of
which semantics are considered “correct”. As changing anything might be a
breaking change, I suggest we apply it only in 3.x (in case we fix anything).
The output of the extended, attached example is:
InternalImpl:
Internal: Param: 1 Text: mit text
Internal: Param: 2 Text: <defaultItf>
Internal: Param: 11 Text: See Sharp!
Keine Überladung für die DoSomething-Methode nimmt 1-Argumente an.
Internal: Param: 21 Text: <defaultItf>
PublicImpl:
Public: Param: 1 Text: mit text
DoSomething() takes exactly 2 arguments (1 given)
Public: Param: 11 Text: See Sharp!
Keine Überladung für die DoSomething-Methode nimmt 1-Argumente an.
Public: Param: 21 Text: <defaultItf>
PublicImplWithDefault:
PublicDefault: Param: 1 Text: mit text
PublicDefault: Param: 2 Text: <defaultImpl>
PublicDefault: Param: 11 Text: See Sharp!
PublicDefault: Param: 12 Text: <defaultImpl>
PublicDefault: Param: 21 Text: <defaultItf>
PublicDefault: Param: 24 Text: <defaultImpl>
PublicDefault: Param: 28 Text: <defaultImpl>
PublicAbcInternalImpl:
InternalABC: Param: 1 Text: mit text
InternalABC: Param: 2 Text: <defaultABC>
InternalABC: Param: 11 Text: See Sharp!
Keine Überladung für die DoSomething-Methode nimmt 1-Argumente an.
InternalABC: Param: 25 Text: <defaultABC>
PublicAbcPublicImpl:
PublicABC: Param: 1 Text: mit text
DoSomething() takes exactly 2 arguments (1 given)
PublicABC: Param: 11 Text: See Sharp!
Keine Überladung für die DoSomething-Methode nimmt 1-Argumente an.
PublicABC: Param: 25 Text: <defaultABC>
PublicAbcPublicImplWithDefault:
PublicABC: Param: 1 Text: mit text
PublicABC: Param: 2 Text: <defaultImpl>
PublicABC: Param: 11 Text: See Sharp!
PublicABC: Param: 12 Text: <defaultImpl>
PublicABC: Param: 25 Text: <defaultABC>
Best regards
Markus Schaber
CODESYS® a trademark of 3S-Smart Software Solutions GmbH
Inspiring Automation Solutions
________________________________
3S-Smart Software Solutions GmbH
Dipl.-Inf. Markus Schaber | Product Development Core Technology
Memminger Str. 151 | 87439 Kempten | Germany
Tel. +49-831-54031-979 | Fax +49-831-54031-50
E-Mail: [email protected]<mailto:[email protected]> | Web:
codesys.com<http://www.codesys.com> | CODESYS store:
store.codesys.com<http://store.codesys.com>
CODESYS forum: forum.codesys.com<http://forum.codesys.com>
Managing Directors: Dipl.Inf. Dieter Hess, Dipl.Inf. Manfred Werner | Trade
register: Kempten HRB 6186 | Tax ID No.: DE 167014915
________________________________
This e-mail may contain confidential and/or privileged information. If you are
not the intended recipient (or have received
this e-mail in error) please notify the sender immediately and destroy this
e-mail. Any unauthorised copying, disclosure
or distribution of the material in this e-mail is strictly forbidden.
From: Slide [mailto:[email protected]]
Sent: Tuesday, August 30, 2016 12:09 PM
To: Markus Schaber; Discussion of IronPython
Subject: Re: [Ironpython-users] Binding problem with default parameters in
public classes
I can see this both ways (bug and not a bug), so let's err on the side of bug
and see if we can make the behaviour match C#.
On Mon, Aug 29, 2016, 23:53 Markus Schaber
<[email protected]<mailto:[email protected]>> wrote:
Hi, Slide,
Using a public abstract base class produces the same result: If the derived
class is internal, the call works fine, if the derived class is public, the
call does not work.
Best regards
Markus Schaber
CODESYS® a trademark of 3S-Smart Software Solutions GmbH
Inspiring Automation Solutions
________________________________
3S-Smart Software Solutions GmbH
Dipl.-Inf. Markus Schaber | Product Development Core Technology
Memminger Str. 151 | 87439 Kempten | Germany
Tel. +49-831-54031-979 | Fax +49-831-54031-50
E-Mail: [email protected]<mailto:[email protected]> | Web:
codesys.com<http://www.codesys.com> | CODESYS store:
store.codesys.com<http://store.codesys.com>
CODESYS forum: forum.codesys.com<http://forum.codesys.com>
Managing Directors: Dipl.Inf. Dieter Hess, Dipl.Inf. Manfred Werner | Trade
register: Kempten HRB 6186 | Tax ID No.: DE 167014915
________________________________
This e-mail may contain confidential and/or privileged information. If you are
not the intended recipient (or have received
this e-mail in error) please notify the sender immediately and destroy this
e-mail. Any unauthorised copying, disclosure
or distribution of the material in this e-mail is strictly forbidden.
From: Slide [mailto:[email protected]<mailto:[email protected]>]
Sent: Monday, August 29, 2016 4:24 PM
To: Markus Schaber; Discussion of IronPython
Subject: Re: [Ironpython-users] Binding problem with default parameters in
public classes
What happens if it's an abstract base class instead of an interface?
On Mon, Aug 29, 2016, 03:25 Markus Schaber
<[email protected]<mailto:[email protected]>> wrote:
Hi,
Our tests recently caught a strange regression in our application. One can make
existing scripts fail by changing an internal class to public.
The attached program reproduces the issue. The problem is that the method has
optional parameters, but those are only declared at the interface.
Now, when the class changes from “internal” to “public”, IronPython binds
directly to the public methods without considering the interfaces any more, and
thus does not recognize the optional parameters.
Now, the question is whether this could be considered a bug in IronPython, or
whether it should be considered a bug to implement an interface method without
replicating the default parameter values…
Best regards
Markus Schaber
CODESYS® a trademark of 3S-Smart Software Solutions GmbH
Inspiring Automation Solutions
________________________________
3S-Smart Software Solutions GmbH
Dipl.-Inf. Markus Schaber | Product Development Core Technology
Memminger Str. 151 | 87439 Kempten | Germany
Tel. +49-831-54031-979 | Fax +49-831-54031-50
E-Mail: [email protected]<mailto:[email protected]> | Web:
codesys.com<http://www.codesys.com> | CODESYS store:
store.codesys.com<http://store.codesys.com>
CODESYS forum: forum.codesys.com<http://forum.codesys.com>
Managing Directors: Dipl.Inf. Dieter Hess, Dipl.Inf. Manfred Werner | Trade
register: Kempten HRB 6186 | Tax ID No.: DE 167014915
________________________________
This e-mail may contain confidential and/or privileged information. If you are
not the intended recipient (or have received
this e-mail in error) please notify the sender immediately and destroy this
e-mail. Any unauthorised copying, disclosure
or distribution of the material in this e-mail is strictly forbidden.
_______________________________________________
Ironpython-users mailing list
[email protected]<mailto:[email protected]>
https://mail.python.org/mailman/listinfo/ironpython-users
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace IronPythonInterfaceBindingTest
{
using IronPython.Hosting;
public interface IFooBar
{
void DoSomething(int param, string text = "<defaultItf>");
}
internal class InternalImpl : IFooBar
{
public void DoSomething(int param, string text)
{
Console.WriteLine("Internal: Param: {0} Text: {1}", param, text ??
"<null>");
}
}
public class PublicImpl : IFooBar
{
public void DoSomething(int param, string text)
{
Console.WriteLine("Public: Param: {0} Text: {1}", param, text ??
"<null>");
}
}
public class PublicImplWithDefault : IFooBar
{
public void DoSomething(int param, string text = "<defaultImpl>")
{
Console.WriteLine("PublicDefault: Param: {0} Text: {1}", param,
text ?? "<null>");
}
}
public abstract class PublicABC
{
public abstract void DoSomething(int param, string text =
"<defaultABC>");
}
internal class PublicAbcInternalImpl : PublicABC
{
public override void DoSomething(int param, string text)
{
Console.WriteLine("InternalABC: Param: {0} Text: {1}", param, text
?? "<null>");
}
}
public class PublicAbcPublicImpl : PublicABC
{
public override void DoSomething(int param, string text)
{
Console.WriteLine("PublicABC: Param: {0} Text: {1}", param, text ??
"<null>");
}
}
public class PublicAbcPublicImplWithDefault : PublicABC
{
public override void DoSomething(int param, string text =
"<defaultImpl>")
{
Console.WriteLine("PublicABC: Param: {0} Text: {1}", param, text ??
"<null>");
}
}
public static class Program
{
const string TESTSCRIPT = "impl.DoSomething(1, 'mit
text')\r\nimpl.DoSomething(2)\r\n";
private static readonly object[] INSTANCES = {
new InternalImpl(),
new PublicImpl(),
new PublicImplWithDefault(),
new PublicAbcInternalImpl(),
new PublicAbcPublicImpl(),
new PublicAbcPublicImplWithDefault()
};
public static void Main()
{
foreach (object instance in INSTANCES)
{
Console.WriteLine("{0}: ", instance.GetType().Name);
var engine = Python.CreateEngine();
var scope = engine.CreateScope();
scope.SetVariable("impl", instance);
try
{
engine.Execute(TESTSCRIPT, scope);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
try
{
dynamic d = instance;
d.DoSomething(11, "See Sharp!");
d.DoSomething(12);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
(instance as IFooBar)?.DoSomething(21);
//(instance as InternalImpl)?.DoSomething(22); -> Compiler Error
//(instance as PublicImpl)?.DoSomething(23); -> Compiler Error
(instance as PublicImplWithDefault)?.DoSomething(24);
(instance as PublicABC)?.DoSomething(25);
//(instance as PublicAbcInternalImpl)?.DoSomething(26); ->
Compiler Error
//(instance as PublicAbcPublicImpl)?.DoSomething(27); ->
Compiler Error
(instance as PublicImplWithDefault)?.DoSomething(28);
Console.WriteLine();
}
Console.ReadKey();
}
}
}
_______________________________________________
Ironpython-users mailing list
[email protected]
https://mail.python.org/mailman/listinfo/ironpython-users