[Ironpython-users] Differences with pyc-compiled assemblies?
Nicholas Devenish
misnomer at gmail.com
Mon Nov 12 02:43:46 CET 2012
On 11 Nov 2012, at 23:06, Jeff Hardy <jdhardy at gmail.com> wrote:
> SQLAlchemy works on IronPython? I didn't know that. Very cool. Is
> there anything that has to be done or does it just work out of the
> box?
It's supposed to work out of the box - one of the reasons I decided to go with IronPython for my current project. I haven't stress tested it, but importing the (source) package and running some simple operations on an in-memory sqlite database all works without issue.
>> Traceback (most recent call last):
>> File "<stdin>", line 1, in <module>
>> File "sqlalchemy\__init__.py", line 52, in <module>
>> File "sqlalchemy\types", line 27, in <module>
>> File "sqlalchemy\schema", line 2670, in <module>
>> File "sqlalchemy\schema", line 2706, in DDLElement
>> File "sqlalchemy\util\deprecations", line 45, in decorate
>> File "sqlalchemy\util\deprecations", line 116, in _decorate_with_warning
>> File "sqlalchemy\util\langhelpers", line 41, in decorate
>> File "c:\Program Files\IronPython 2.7\Lib\inspect.py", line 814, in getargspec
>> File "c:\Program Files\IronPython 2.7\Lib\inspect.py", line 758, in getargs
>> IndexError: index out of range: 2
> In inspect.py, just before line 758, it looks at co.co_argcount and
> co.co_varnames and assumes that they are the same length, but my guess
> is that they might not be when compiled with pyc. If you can figure
> out exactly what getargspec is being called on, that might help make a
> simpler reproduction that I can work off of.
So, I've traced down the stack trace with some tested output. This is what it seems to be doing:
> Starting with the wrapped function (though the line number seems off slightly,
> everything else in the stack trace and debug output before the exception matches
> up exactly):
>
> @util.deprecated("0.7", "(deprecated message)")
> def execute_at(self, event_name, target):
> def call_event(target, connection, **kw):
> if self._should_execute_deprecated(event_name,
> target, connection, **kw):
> return connection.execute(self.against(target))
> event.listen(target, "" + event_name.replace('-', '_'), call_event)
>
>
> the deprecated decorator returns this function as the decorator:
>
> def decorate(fn):
> print "In deprecated decorator: {}, {}".format(fn, message % dict(func=fn.__name__))
> return _decorate_with_warning(
> fn, exc.SADeprecationWarning,
> message % dict(func=fn.__name__), header)
>
> and this calls through to _decorate_with_warning:
>
> def _decorate_with_warning(func, wtype, message, docstring_header=None):
> ...
> @decorator
> def warned(fn, *args, **kwargs):
> warnings.warn(wtype(message), stacklevel=3)
> return fn(*args, **kwargs)
>
> decorated = warned(func)
> ... (above line triggers the decorator)
>
>
> The @decorator is:
>
> def decorator(target):
> """A signature-matching decorator factory."""
>
> def decorate(fn):
> if not inspect.isfunction(fn):
> raise Exception("not a decoratable function")
> print "Decorating: {}".format(fn)
> spec = inspect_getfullargspec(fn)
> .........
> return update_wrapper(decorate, target)
> # update_wrapper is from python's functools
>
> And decorate calls through into inspect.py's aliased getfullargspec:
>
> def getargspec(func):
> if ismethod(func):
> func = func.im_func
> if not isfunction(func):
> raise TypeError('{!r} is not a Python function'.format(func))
> args, varargs, varkw = getargs(func.func_code)
>
> That calls getargs:
>
> def getargs(co):
> if not iscode(co):
> raise TypeError('{!r} is not a code object'.format(co))
>
> nargs = co.co_argcount
> names = co.co_varnames
> args = list(names[:nargs])
> step = 0
>
> for i in range(nargs):
> if args[i][:1] in ('', '.'):
>
> With values for the variables:
>
> print "getargs:"
> print " args: {}".format(args)
> print " nargs: {}".format(nargs)
> print " names: {}".format(names)
>
> And the output from these print statements:
>
> getargs:
> args: ['target', 'call_event']
> nargs: 3
> names: ('target', 'call_event')
Is this any help? It's 2am now, but I'll continue poking at this tomorrow.
Thanks,
Nick
More information about the Ironpython-users
mailing list