[plugins/help] Triggering node visits?
まだ誰も着手していません。
- 主要言語
- Python
- スター
- 20.6k
- フォーク
- 3.3k
- PR マージ指標
- PR 指標を取得中
説明
Hello there 👋
First of all, I post here instead of on Gitter because I think my question is a bit long and it would pollute the thread while being hard to respond too. Also, Thanks for all the documentation in source code, it helps a lot already!
I'm trying to write a plugin for my paramclasses library and I would love some help! For a starting point, I'll focus on my protected function/decorator, which essentially provides runtime equivalent for both typing.finaland typing.Final during paramclasses' definition:
class Foo(ParamClass):
x = protected(0) # Unmodifiable in instances and subclasses
@protected
def bar(self) -> None:
"""Works on methods."""
@protected
@property
def baz(self) -> int:
"""Also works on properties."""
return 0
I started understanding a bit more how mypy plugins work, and I currently have the following:
METAPARAMCLASS_FULLNAME = "paramclasses.paramclasses._MetaParamClass" # Paramclasses have this as metaclass
class CustomPlugin(Plugin):
"""Help mypy undestand ``@protected`` and ``protected()``."""
def get_metaclass_hook(self, fullname) -> Callable[[ClassDefContext], None] | None:
"""Update paramclass definition."""
return paramclass_finder_hook
def get_base_class_hook(self, fullname) -> Callable[[ClassDefContext], None] | None:
"""Update paramclass definition."""
return paramclass_finder_hook
def paramclass_finder_hook(ctx: ClassDefContext):
"""Identify paramclasses and trigger class def modification."""
mcs = ctx.cls.info.metaclass_type
if mcs is not None and mcs.type.fullname == METAPARAMCLASS_FULLNAME:
modify_paramclass_def(ctx.cls)
def modify_paramclass_def(cls: ClassDef) -> None:
"""Handle ``@property`` and ``protected()``."""
replace_protected_decorator_with_final(cls)
replace_protected_assignment_with_Final(cls)
def replace_protected_decorator_with_final(cls: ClassDef) -> None:
"""Visit decorator nodes, move @protected, add to original_decorators, mark node as final."""
# Help pls!
As you can see, I think I'm pretty close to a first POC, I just need to know how to visit cls in replace_protected_decorator_with_final and modify targetted nodes. For that, I'll take inspiration from mypy.semanal.SemanticAnalyzer.visit_decorator() I think?
But I have so many questions:
- Is my overall approach sound/in the spirit of mypy plugins API?
- How can I trigger a visit? I thought about writing a custom semantic analyzer but I don't know how to "trigger" it?
- If I write one, should my
SemanticAnalyzerinherit from(NodeVisitor[None], SemanticAnalyzerInterface, SemanticAnalyzerPluginInterface)just like the one from mypy/semanal.py? I don't really understand what's useful and when. - Should I carry out both
replace_protected_decorator_with_finalandreplace_protected_assignment_with_Finalsimultaneously with a unique semantic analyzer?
Thanks a lot in advance!!!
Élie
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
調査の方向性
issue 内のプラグインフック実装から始め、特に SemanticAnalyzer.visit_decorator() に注目して mypy/semanal.py を読みます。既存のプラグイン API が対象のクラスノードの訪問と変更をサポートしているか、またカスタムセマンティックアナライザーが適切かどうかを判断します。サポートされているアプローチを確立するか、要求されたトラバーサルが利用できないことを文書化できれば完了です。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- python
- 領域
- tooling
- issue の種類
- 機能追加
- 難易度
- 5/5
- 見積もり時間
- 1週間以上
- 活発さ
- 停滞
- 明瞭さ
- 説明が足りない
- 初心者へのやさしさ
- 25/100