Alex
Alex

Reputation: 4473

IronPython strange behaviour

I have file A.py:

...
from System.IO import Directory
...
execfile('B.py')

and file B.py:

...
result = ['a','b'].Contains('a')

Such combination works fine. But if I comment this particular import line at A.py then B.py complains:

AttributeError: 'list' object has no attribute 'Contains'

It looks strange for me, especially B.py alone runs fine.

Is there some 'list' override in module System.IO? Is there way to determine what is changed during this import? Or avoid such strange behavior?

Upvotes: 1

Views: 154

Answers (1)

Simon Opelt
Simon Opelt

Reputation: 6211

B.py on its own (on IPy 2.7.4) also results in the error you provided. It should as there is no built-in method that would bind for that call. You could also try to reproduce this on standard python to make sure.

The way you "include" B.py into A.py has inherent risks and problems at least because of missing control over the scope the code in B is executed against. If you wrap your code in a proper module/classes you can be sure that there are no issues of that sort.

This could (simplified, just a function, no classes etc.) look like:

from B import getResult
getResult()
from System.IO import Directory
getResult()

and

def getResult():
    from System.IO import Directory
    result = ['a','b'].Contains('a')
    return result

As you can see the function getResult can ensure that all imports and other scope properties are correct and it will work whether or not the call site has the given import.

As for why the import of System.IO.Directory causes binding to IronPython.dll!IronPython.Runtime.List.Contains(object value) is not clear and would require a close look at IronPython's internal implementation.

If you mind the actual import to System.IO.Directory but don't want to refactor the code you could go with LINQ for IronPython/ImportExtensions as that would provide a Contains method as well. This will not reduce but actually increase your importing boilerplate but be more to the point.

import clr
clr.AddReference("System.Core")
import System
clr.ImportExtensions(System.Linq)

result = ['a','b'].Contains('a')

Upvotes: 1

Related Questions