[SciPy-Dev] usage of inspect.getargspec ?

Warren Weckesser warren.weckesser at enthought.com
Thu Jan 5 23:20:21 EST 2012


On Thu, Jan 5, 2012 at 10:07 PM, Warren Weckesser <
warren.weckesser at enthought.com> wrote:

>
>
> On Thu, Jan 5, 2012 at 9:09 PM, <josef.pktd at gmail.com> wrote:
>
>> triggered by the recent commit, I started to look a bit more at
>> inspect.getargspec
>>
>>
>> https://github.com/scipy/scipy/commit/c9c2d66701583984589c88c08c478e2fc6d9f4ec#L1R1213
>>
>> Until now I have seen it mainly in convenience code were it makes it
>> easier for users but that I usually don't use, in this case it is part
>> of essential code.
>>
>> The main problem with inspect.getargspec is that it gets easily
>> confused by `self` if it is an instance method and by keywords and
>> flexible arguments.
>>
>>
>
> Heh--you might be projecting a bit here.  You or I might get confused, but
> I bet getargspec knows exactly what it is doing. :)
>
>
>
>> recent fix for curve_fit https://github.com/scipy/scipy/pull/92
>> my only other experience is with numpy.vectorize that has some tricky
>> features and IIRC has some cases of flexible arguments that don't
>> work.
>>
>> I don't think the changes to fmin_ncg break anything in statsmodels
>> since we have identical simple signatures for the main functions,
>> hessians and gradients, but I think it would break if we add a keyword
>> argument to the Hessians.
>> It also would be possible to work around any limitations by writing a
>> wrapper or a lambda function.
>>
>>
>> What experience do others have with inspect?
>> My experience is mostly unpleasant but I never looked much at the
>> details of inspect, just avoided it as much as possible.
>> Is it ok to use it in basic library code like the optimizers?
>>
>>
>> Just asking for general comments and since the pull request is closed.
>>
>>
>
> getargspec does not work with, for example, an instance of a class that
> implements __callable__,
>

I meant __call__ here.


> so the docstring for minimize is being too optimistic when it says that
> hess must be callable.  It actually must be a function or method.
>
> It looks like jac will also not work if it is an instance of a callable
> class:
>
> In [28]: p = np.poly1d([3,2,1])
>
> In [29]: minimize(p, 1, jac=p.deriv(), method='Newton-CG')
> ---------------------------------------------------------------------------
> AttributeError                            Traceback (most recent call last)
> /Users/warren/<ipython-input-29-4ff757edc58a> in <module>()
> ----> 1 minimize(p, 1, jac=p.deriv(), method='Newton-CG')
>
> /Users/warren/local_scipy/lib/python2.7/site-packages/scipy/optimize/minimize.pyc
> in minimize(fun, x0, args, method, jac, hess, options, full_output,
> callback, retall)
>     203     elif method.lower() == 'newton-cg':
>     204         return _minimize_newtoncg(fun, x0, args, jac, hess,
> options,
> --> 205                                   full_output, retall, callback)
>     206     elif method.lower() == 'anneal':
>     207         if callback:
>
> /Users/warren/local_scipy/lib/python2.7/site-packages/scipy/optimize/optimize.pyc
> in _minimize_newtoncg(fun, x0, args, jac, hess, options, full_output,
> retall, callback)
>    1202     Also note that the `jac` parameter (Jacobian) is required.
>    1203     """
> -> 1204     if jac == None:
>    1205         raise ValueError('Jacobian is required for Newton-CG
> method')
>    1206     f = fun
>
> /Library/Frameworks/Python.framework/Versions/7.2/lib/python2.7/site-packages/numpy/lib/polynomial.py
> in __eq__(self, other)
>    1159
>    1160     def __eq__(self, other):
> -> 1161         return NX.alltrue(self.coeffs == other.coeffs)
>    1162
>    1163     def __ne__(self, other):
>
> AttributeError: 'NoneType' object has no attribute 'coeffs'
>


Whoops--I just noticed that this problem was more specific to jac being a
poly1d instance.  A different example shows that jac can be an instance of
a callable class:

In [59]: class Foo(object):
   ....:     def __call__(self, x):
   ....:         return x**2
   ....:

In [60]: class dFoo(object):
   ....:     def __call__(self, x):
   ....:         return 2*x
   ....:

In [61]: f = Foo()

In [62]: df = dFoo()

In [63]: minimize(f, 1, jac=df, method='Newton-CG')
Optimization terminated successfully.
         Current function value: 0.000000
         Iterations: 2
         Function evaluations: 3
         Gradient evaluations: 4
         Hessian evaluations: 0
Out[63]: array([ 0.])


Warren
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/scipy-dev/attachments/20120105/0979e468/attachment.html>


More information about the SciPy-Dev mailing list