2017-09-04 7 views
2

Le module inspect de Python ne semble pas pouvoir inspecter les signatures de fonctions "intégrées", qui incluent des fonctions définies dans des modules d'extension C, comme celles définies par Cython. Est-il possible d'obtenir la signature d'une fonction Python que vous avez définie dans un tel module, et plus particulièrement dans Cython? Je cherche à être en mesure de trouver les arguments de mots clés disponibles.Comment introspecter une fonction définie dans un module d'extension Cython C

MWE:

# mwe.pyx 
def example(a, b=None):                                      
    pass  

et

import pyximport; pyximport.install()                                   
import mwe                                          
import inspect                                         

inspect.signature(mwe.example) 

rendements:

Traceback (most recent call last):                                   
    File "mwe_py.py", line 5, in <module>                                  
    inspect.signature(mwe.example)                                   
    File "/nix/store/134l79vxb91w8mhxxkj6kb5llf7dmwpm-python3-3.4.5/lib/python3.4/inspect.py", line 2063, in signature               
    return _signature_internal(obj)                                   
    File "/nix/store/134l79vxb91w8mhxxkj6kb5llf7dmwpm-python3-3.4.5/lib/python3.4/inspect.py", line 1965, in _signature_internal            
    skip_bound_arg=skip_bound_arg)                                   
    File "/nix/store/134l79vxb91w8mhxxkj6kb5llf7dmwpm-python3-3.4.5/lib/python3.4/inspect.py", line 1890, in _signature_from_builtin           
    raise ValueError("no signature found for builtin {!r}".format(func))                          
ValueError: no signature found for builtin <built-in function example>  

En Python 3.4.5 et cython 0.24.1

+1

Pourquoi cela ne serait-il pas possible? 'inspect.signature (all)' (par exemple pour extraire la signature de ['all'] (https://docs.python.org/library/functions.html#all)) fonctionne très bien' '. S'il vous plaît fournir un [mcve] afin que les réponses peuvent réellement vous montrer comment le faire dans * votre cas *. – MSeifert

+2

Copie possible de [Python inspect.getargspec avec fonction intégrée] (https://stackoverflow.com/questions/11343191/python-inspect-getargspec-with-built-in-function) – DavidW

+1

Également pertinent: https: // stackoverflow.com/questions/1104823/python-c-extension-method-signatures-for-documentation – DavidW

Répondre

2

J'ai rétractés mon double suggestion (en disant qu'il était imposé sible ...) ayant enquêté plus loin. Il semble fonctionner correctement avec les versions relativement récentes de Cython (v0.23.4) et Python 3.4.4.

import cython 
import inspect 
scope = cython.inline("""def f(a,*args,b=False): pass """) 
print(inspect.getfullargspec(scope['f'])) 

donne la sortie

FullArgSpec(args=['a'], varargs='args', varkw=None, defaults=None, kwonlyargs=['b'], kwonlydefaults={'b': False}, annotations={})


également mentionné dans the documentation is the compilation option "binding" ce qui rend apparemment ce détail plus accessible (bien que je ne l'ai pas besoin).


J'ai le sentiment que cela peut dépendre de l'amélioration de inspect fait relativement récemment (peut-être this fix) donc si vous utilisez Python 2, vous êtes probablement hors de la chance.


Edit: votre exemple ne fonctionne que si vous utilisez l'option de compilation binding:

import cython 
@cython.binding(True) 
def example(a, b=None):                                      
    pass 

Je soupçonne que inline ajoute automatiquement (mais le code pour faire inline est suffisamment alambiquée que je peux » t trouver la preuve de cela de toute façon). Vous pouvez également le définir comme une option au niveau du fichier.

+0

Merci David, j'ai mis à jour la question avec un MWE, ne semble pas fonctionner avec une importation par opposition à la fonction inline. – Gilly

+0

@ Gilly Voir edit - c'est juste un cas de s'assurer que vous utilisez 'binding' – DavidW

+0

Merci un tas! Exactement ce que je cherchais. – Gilly