IronLanguages / ironpython2

Implementation of the Python programming language for .NET Framework; built on top of the Dynamic Language Runtime (DLR).
http://ironpython.net
Apache License 2.0
1.08k stars 229 forks source link

StackOverflow when enumerating dynamic members of IMOs #97

Open slide opened 7 years ago

slide commented 7 years ago

From @ironpythonbot on December 9, 2014 18:13

Tested on IronPyton 2.7.4

import System
import clr
clr.AddReference("System.Core")
from System.Dynamic import DynamicObject

class Foo(DynamicObject):
      def bar():
          pass

f = Foo()
System.ComponentModel.TypeDescriptor.GetProperties(f)

Work Item Details

Original CodePlex Issue: Issue 34893 Status: Active Reason Closed: Unassigned Assigned to: jdhardy Reported on: Jan 15 at 10:46 AM Reported by: becio Updated on: Apr 9 at 11:21 PM Updated by: jdhardy

Copied from original issue: IronLanguages/main#1100

slide commented 7 years ago

From @ironpythonbot on December 9, 2014 18:13

On 2014-04-06 07:49:09 UTC, jdhardy commented:

The interesting bits seem to be InstanceOps.DynamicDir and PythonType.TryGetCustomDir.

slide commented 7 years ago

From @ironpythonbot on December 9, 2014 18:13

On 2014-04-07 06:04:46 UTC, becio commented:

True, this bug affects the core interoperability between dynamic languages, I used DO in the example just a synonym of ANY external dynamic class.

slide commented 7 years ago

From @ironpythonbot on December 9, 2014 18:13

On 2014-04-10 06:21:50 UTC, jdhardy commented:

This has proven to be delightfully nasty to solve.

The basic issue is that PythonType.GetMemberNames is called on f; that checks to see if it has a custom dir, which it does, provided by DynamicObject, so it ultimately calls MetaUserObject.GetDynamicMemberNames; seeing as this is a Python object, it then calls Python.GetMemberNames...

Everything I've tried breaks one of: custom dir on Python types, getting dynamic member names from other dynamic types, or getting the dynamic member names from a Python type from another language.

I feel there is a solution here, but I just can't put my finger on it. I'm all but certain it'll involve special-casing the situation where a Python class derives from a DynamicObject (really, IDMOP) class. It's just a matter of finding it.

slozier commented 4 years ago

Ran into this today via ctypes:

import ctypes
mciSendString = ctypes.windll.winmm.mciSendStringA
dir(mciSendString)