python / python/mypy

[plugins/help] Triggering node visits?

Đang mở
#19,481 7 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

question
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:

  1. Is my overall approach sound/in the spirit of mypy plugins API?
  2. How can I trigger a visit? I thought about writing a custom semantic analyzer but I don't know how to "trigger" it?
  3. If I write one, should my SemanticAnalyzer inherit from (NodeVisitor[None], SemanticAnalyzerInterface, SemanticAnalyzerPluginInterface) just like the one from mypy/semanal.py? I don't really understand what's useful and when.
  4. Should I carry out both replace_protected_decorator_with_final and replace_protected_assignment_with_Final simultaneously with a unique semantic analyzer?

Thanks a lot in advance!!!
Élie

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. 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.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. 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

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.