[plugins/help] Triggering node visits?
Chưa có ai nhận issue này.
- Ngôn ngữ chính
- Python
- Star
- 20.6k
- Fork
- 3.3k
- Chỉ số merge pull request
- Chỉ số pull request đang chờ
Mô tả
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
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Hướng nghiên cứu
Bắt đầu với các triển khai plugin hook trong issue và đọc mypy/semanal.py, đặc biệt là SemanticAnalyzer.visit_decorator(). Xác định xem plugin API hiện có có hỗ trợ việc truy cập và sửa đổi các class node mục tiêu hay không, cũng như liệu một semantic analyzer tùy chỉnh có phù hợp hay không; công việc được xem là hoàn tất khi đã xác lập một cách tiếp cận được hỗ trợ hoặc ghi lại rằng traversal được yêu cầu không khả dụng.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Đánh giá
- Công nghệ
- python
- Lĩnh vực
- tooling
- Loại issue
- Tính năng
- Độ khó
- 5/5
- Thời gian dự kiến
- Hơn một tuần
- Mức độ hoạt động
- Đình trệ
- Độ rõ ràng
- Cần làm rõ
- Mức phù hợp với người mới
- 25/100