2017-02-13 6 views
0

Python 3(toga)用のUIライブラリ用の静的ドキュメントジェネレータを作成しようとしています。プロジェクト内モジュールの属性をインポートせずに検査する方法

のサブディレクトリがあります

  • iOS
    • setup.py
    • toga_iOS
      • __init__.py
      • app.py
  • mac
    • setup.py
    • toga_mac
      • __init__.py
      • app.py

私は、ディレクトリを反復処理し、toga_xモジュールで__all__属性の値を取得したいです。私が持っている問題は、各モジュールがそのプラットフォームにインストールされるように設計されていることです。 Windowsの1は、Mac上でWindows、Mac上でインストールするPythonパッケージを必要とするなど

私はのimportlibか__import__を使用している場合__init__.pyの各ファイル内では、プラットフォーム固有のパッケージをインポートしますので、それは例えば、失敗しました

PLATFORM_LIST = { 
    'android': 'Android', 
    'cocoa': 'Mac OS cocoa', 
    'gtk': 'GTK +' 
} 

for module, label in PLATFORM_LIST.items(): 
    print(module) 
    sys.path.append(os.path.join('../src', 
           module)) 
    module = importlib.import_module('toga_'+module) 
    sys.modules[module] = module 
    _all = getattr(module, '__all__') 

"ImportError:No android 'という名前のモジュールがありません。

多くのオプション、ast、pylint、compile、inspectlibがあります。すべての依存モジュールをインストールすることなく__all__の値を取得するための最良の方法はどれですか?

+0

'__all__'が動的に作成される場合はどうなりますか?(必ずしも異なるプラットフォームでは異なるわけではありませんが、単一の代入ステートメントより多くなる可能性があります) –

+0

サポートするAPIを文書化する方法として、各パッケージで静的に宣言されています。 –

答えて

2

あなたはPythonのソース・ファイルで静的割り当てノードを見つけるためにastを使用することができます。

import ast 


def get_declaration_from_source(text, name="__all__"): 
    """gets a single declaration from python source code""" 
    tree = ast.parse(text) 
    #walk through each statement (more or less) in the module 
    for node in tree.body: 
     #if assigning to a single target (a = b= 5 is multiple) 
     if isinstance(node, ast.Assign) and len(node.targets)==1: 
      target = node.targets[0] 
      #if assigning to the name we are looking for 
      if isinstance(target, ast.Name) and target.id == name: 
       #use literal_eval to get the actual value, can raise ValueError if not a literal value. 
       return ast.literal_eval(node.value) 
    raise NameError("name %r was not found"%(name,)) 

は、一例としてrandomソースファイルを使用することができます場合ast.parseSyntaxErrorを上げることができ

import random 
with open(random.__file__, "r") as f: 
    names = get_declaration_from_source(f.read()) 

>>> names 
['Random', 'seed', 'random', 'uniform', 'randint', 'choice', 'sample', 'randrange', 'shuffle', 'normalvariate', 'lognormvariate', 'expovariate', 'vonmisesvariate', 'gammavariate', 'triangular', 'gauss', 'betavariate', 'paretovariate', 'weibullvariate', 'getstate', 'setstate', 'getrandbits', 'choices', 'SystemRandom'] 

注意をソースコードに構文エラーがあります(コンパイル時に他のエラーが発生する可能性があります)。ast.literal_evalは、値がPythonリテラルでない場合はValueErrorになりますあなたは問題にすべきではないとコメントしました、歓声。

関連する問題