Skip to content

"Missing self argument" error after dynamically replacing method #350

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
shiw-yang opened this issue May 13, 2025 · 1 comment · May be fixed by astral-sh/ruff#18237
Open

"Missing self argument" error after dynamically replacing method #350

shiw-yang opened this issue May 13, 2025 · 1 comment · May be fixed by astral-sh/ruff#18237
Assignees
Labels
attribute access Instance attributes, class attributes, etc. bug Something isn't working calls Issues relating to call-signature checking and diagnostics

Comments

@shiw-yang
Copy link

Summary

In the provided example, I dynamically replace the A.f1 method with f1_replace through the f2 function. After this replacement, ty reports an error:
No argument provided for required parameter 'self' of function 'f1' when calling a.f1(), though the code actually runs correctly.

Steps to Reproduce:

class A:
    def f1(self):
        print("f1")

    def f1_replace(self):
        print("replace")

    def f2(self):
        self.f1 = self.f1_replace


a = A() 
a.f1()  # No argument provided for required parameter `self` of function `f1`
a.f2()
a.f1()  # No argument provided for required parameter `self` of function `f1`

then use ty check show:

$ ty check main.py
WARN ty is pre-release software and not ready for production use. Expect to encounter bugs, missing features, and fatal errors.
error[missing-argument]: No argument provided for required parameter `self` of function `f1`
  --> main.py:39:1
   |
38 | a = A()
39 | a.f1()
   | ^^^^^^
40 | a.f2()
41 | a.f1()
   |
info: Union variant `def f1(self) -> Unknown` is incompatible with this call site
info: Attempted to call union type `(bound method A.f1() -> Unknown) | (def f1(self) -> Unknown)`
info: `missing-argument` is enabled by default

error[missing-argument]: No argument provided for required parameter `self` of function `f1`
  --> main.py:41:1
   |
39 | a.f1()
40 | a.f2()
41 | a.f1()
   | ^^^^^^
   |
info: Union variant `def f1(self) -> Unknown` is incompatible with this call site
info: Attempted to call union type `(bound method A.f1() -> Unknown) | (def f1(self) -> Unknown)`
info: `missing-argument` is enabled by default

Found 2 diagnostics

Version

ty 0.0.0-alpha.8

@sharkdp sharkdp added bug Something isn't working calls Issues relating to call-signature checking and diagnostics attribute access Instance attributes, class attributes, etc. labels May 13, 2025
@sharkdp
Copy link
Contributor

sharkdp commented May 13, 2025

Thank you for reporting this. This is a bug in ty.

The problem here seems to be that we recognize the instance attribute assignment to self.f1, but since we don't understand the type of self set (#159), we infer Unknown for the implicit instance attribute f1. We union that with the type of the def f1 method definition, but fail to bind the self argument (because we think it's an instance attribute and don't invoke the descriptor protocol?).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
attribute access Instance attributes, class attributes, etc. bug Something isn't working calls Issues relating to call-signature checking and diagnostics
Projects
None yet
2 participants