-
Notifications
You must be signed in to change notification settings - Fork 9
Errors about mismatched arguments, especially self #202
Comments
I was never happy with just guessing "add self", but took it as a decent first step. I'll definitely have to explore using Note to self: this could be useful https://stackoverflow.com/questions/67639234/count-how-many-arguments-passed-as-positional for further inspiration. |
Without (yet) using Here are three different examples that were treated the same way before with the simple suggestion of adding "self". First example, inspired from a StackOverflow question. class Pet(object):
# Inspired by a StackOverflow question
def __init__(self,name=""):
self.name = name
self.toys = []
def add_toy(self, toy=None):
if toy is not None:
self.toys.append(toy)
return self.toys
def __str__(self):
toys_list = add_toy()
if self.toys:
return "{} has the following toys: {}".format(self.name, toys_list)
else:
return "{} has no toys".format(self.name)
a = Pet('a')
print(a) Here is the explanation
A second, slightly different example class Pet(object):
# Inspired by a StackOverflow question
def __init__(self,name=""):
self.name = name
self.toys = []
def add_toy(self, toy=None):
if toy is not None:
self.toys.append(toy)
return self.toys
def __str__(self):
toys_list = add_toy(self, 'something')
if self.toys:
return "{} has the following toys: {}".format(self.name, toys_list)
else:
return "{} has no toys".format(self.name)
a = Pet('a')
print(a) and the explanation
Finally, a very different example where, once again, the previous explanation was to add
|
@alexmojaki It it be possible with |
The Executing object has an attribute For an arbitrary node, i.e. not necessarily the executing node, there's For the text of any node, use You may not actually want the full text if it's a compound statement which could easily be hundreds of lines long, in which case you want a stack_data piece. |
I couldn't figure out what you meant by using a stack_data piece. This is what I have now, which works with my current tests: The purpose is to be able to capture the |
See the README at https://github.com/alexmojaki/stack_data
If the node of interest is contained in the condition of an You mentioned pieces in #139 so I think you've seen them before.
If you still want the full statement, you should probably use |
Since this issue was filed, I made a few changes which I believe do provide suggestions that would not be misleading (in that they would not yield a I'm starting to migrate relevant issues from this repository to the newer ones, before freezing this repo. I am thinking that I can close this specific issue but will wait for some feedback. |
I was looking at this question: https://stackoverflow.com/questions/67034823/trying-to-use-the-return-value-from-one-function-in-another-but-getting-undefine
The poster has made all sorts of errors and their code is generally weird, but I'm just going to focus on the fact that they define a method
def add_toys(self,toys)
which they try to call withadd_toys(self,toys)
. I put the code into futurecoder to see if it could guide them to a fix. friendly and didyoumean correctly suggestself.add_toys
to fix the first exception andself.toys
for the next one, e.g:First of all, I think "The local object
<Pet object>
" could probably be improved a bit to something like "The local variableself
with value<Pet object>
". But that's a side point.My main point is that after you follow the suggestions you get
self.add_toys(self,self.toys)
. This gives the errorTypeError: add_toys() takes 2 positional arguments but 3 were given
. The explanation given is:That's a good guess from friendly and I understand why it's that way but in this case it's obviously incorrect.
More generally, the whole matter of auto-binding self in methods is very confusing for beginners, errors along these lines are common, and I can't imagine how confusing it must be to be told that they passed 3 positional arguments when they only passed 2 that they know of. Where is that third argument? What on earth is Python talking about?
For all errors about binding arguments, executing can help a lot:
ast.Call
so you don't get an internal error when handling something likedef __add__(self, other, foo):
self
andself.toys
. I imagine "positional argument" sounds scary and confusing to some.n+1
positional arguments but you only seen
, you can guess thatself
has been provided behind the scenes and explain this to the user. This is more general than the above example - it doesn't matter how many arguments the user provided, how many they were supposed to provide, or what the arguments were (e.g. if they passedself
), just that discrepancy between the source code and the message.pure_eval
to getnode.func
then you will know what they were trying to call. Then withinspect.signature
you can see what arguments they're supposed to provide and explain how Python attempted to bind them. In this caseinspect.signature(self.add_toys)
is just(toys)
, whileinspect.signature(self.add_toys.__func__)
is(self, toys)
which might also be useful.The text was updated successfully, but these errors were encountered: