Skip to content
This repository has been archived by the owner on Sep 14, 2018. It is now read-only.

Misleading ArgumentTypeException message when calling C# method #1660

Closed
walkindude opened this issue May 26, 2017 · 6 comments
Closed

Misleading ArgumentTypeException message when calling C# method #1660

walkindude opened this issue May 26, 2017 · 6 comments

Comments

@walkindude
Copy link

walkindude commented May 26, 2017

Hello, this is not a bug per se, but rather something I just noticed. I'm including a minimal example console app that will throw with the unexpected message Expected Char, got str, further discussion below the code.

By the way, this is IronPython v2.7.7 on .NET 4.

    class Program
    {
        static void Main(string[] args)
        {
            var engine = IronPython.Hosting.Python.CreateEngine();

            var foo = new Foo();
            var locals = new Dictionary<string, object> {{"foo", foo}};

            var scope = engine.CreateScope(locals);

            var result = engine.Execute("foo.Bar('code', 'a', 7.2)",scope);
            
            Console.ReadLine();
        }
    }

    public class Foo
    {
        public string Bar(string x, char y, float z = 0)
        {
            return string.Format("{0}, {1}, {2}", x, y, z);
        }
    }

Now, the signature of method Bar of class Foo is of course wrong, in that the last parameter should be double rather than float (or we would need to pass in a System.Single to begin with).

The exception message is a bit misleading, though: Expected Char, got str is not really the hint I would expect. I scratched my head for a minute before realizing I had made a dumb mistake. It seems like it should say something along the lines of Expected Single, got Double.

Just thought I would let you guys know.

@slozier
Copy link
Contributor

slozier commented May 26, 2017

Are you sure your minimal example is correct? Seems to me like Expected Char, got str is the correct message in that Bar expects a char but you're passing it the string a.

@walkindude
Copy link
Author

walkindude commented May 26, 2017

I'm pretty confident it is correct, yes. If you change Bar to take a double instead of a float, the call will succeed, with 'a' being correctly cast to char.

Of course, passing 'aaa' instead of 'a' will throw as intended.

EDIT: furthermore, if you change the Python part to leave out the third parameter, again everything works flawlessly.

@slozier
Copy link
Contributor

slozier commented May 26, 2017

Ah I see. I ran a few more tests and it seems to be an issue only when using char and float together in the definition. Seems like a bug. Here's the amended test code:

    class Program
    {
        static void Main(string[] args)
        {
            var engine = IronPython.Hosting.Python.CreateEngine();
            var foo = new Foo();
            var locals = new Dictionary<string, object> { { "foo", foo } };
            var scope = engine.CreateScope(locals);
            var result = engine.Execute(@"
print foo.Bar(x='a')
print foo.Bar(y=7.2)
print foo.Bar(x='a', y=7.2)
", scope);
            Console.ReadLine();
        }
    }

    public class Foo
    {
        public string Bar(char x='0', float y=0) => string.Format("{0}, {1}", x, y);
    }

@walkindude
Copy link
Author

Yes, to my untrained eye it really does look like some weird interaction taking place when a char parameters enters the picture.

The first parameter to Bar was there just because it was taken from the actual code I needed to call from IronPython, I forgot to leave it out. Sorry about that.

@slozier
Copy link
Contributor

slozier commented May 30, 2017

After doing a bit of digging, it appears that the DLR uses different "narrowing levels" to figure out what type conversions are allowed. Looking at IronPython.Runtime.Converter.HasNarrowingConversion the string to char conversion is at level "IndexOperator" while the double to single conversion is at level "All". It looks like if the narrowing conversions are not all on the same level the DLR will fail to find the appropriate overload.

@slide
Copy link
Contributor

slide commented Jun 5, 2017

This issue was moved to IronLanguages/ironpython2#15

@slide slide closed this as completed Jun 5, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants