Skip to content
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

When a TypeError is raised due to invalid arguments to a method, it should use __qualname__ to identify the class the method is in #71576

Closed
BlckKnght mannequin opened this issue Jun 26, 2016 · 3 comments
Labels
type-feature A feature request or enhancement

Comments

@BlckKnght
Copy link
Mannequin

BlckKnght mannequin commented Jun 26, 2016

BPO 27389
Nosy @vadmium, @BlckKnght
Superseder
  • bpo-2786: Names in function call exception should have class names, if they're methods
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = <Date 2016-08-05.05:40:52.032>
    created_at = <Date 2016-06-26.03:35:42.645>
    labels = ['type-feature']
    title = 'When a TypeError is raised due to invalid arguments to a method, it should use __qualname__ to identify the class the method is in'
    updated_at = <Date 2016-08-05.06:45:11.197>
    user = 'https://github.com/BlckKnght'

    bugs.python.org fields:

    activity = <Date 2016-08-05.06:45:11.197>
    actor = 'serhiy.storchaka'
    assignee = 'none'
    closed = True
    closed_date = <Date 2016-08-05.05:40:52.032>
    closer = 'Steven.Barker'
    components = []
    creation = <Date 2016-06-26.03:35:42.645>
    creator = 'Steven.Barker'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 27389
    keywords = []
    message_count = 3.0
    messages = ['269274', '269283', '272014']
    nosy_count = 2.0
    nosy_names = ['martin.panter', 'Steven.Barker']
    pr_nums = []
    priority = 'normal'
    resolution = 'duplicate'
    stage = None
    status = 'closed'
    superseder = '2786'
    type = 'enhancement'
    url = 'https://bugs.python.org/issue27389'
    versions = ['Python 3.6']

    @BlckKnght
    Copy link
    Mannequin Author

    BlckKnght mannequin commented Jun 26, 2016

    When a method is called with incorrect arguments (too many or too few, for instance), a TypeError is raised. The message in the TypeError generally of the form:

    foo() takes 2 positional arguments but 3 were given
    

    I think the message should include the class name along with the method name, so it would say SomeClass.foo instead of just foo. Since that is SomeClass.foo's qualname, it should not be too hard to get the right name in most situations.

    Here's an example showing how the current error messages can be ambiguous:

    class A:
        def foo(self, x):
            pass
    
    class B:
        def foo(self, x, y): # different method signature!
            pass
    
    lst = [A(), B()]
    
    for item in lst:
        item.foo(1)  # raises TypeError: foo() missing 1 required positional argument: 'y'"
    
    for item in lst:
        item.foo(1, 2) # raises "TypeError: foo() takes 2 positional arguments but 3 were given"

    In neither loop is is clear which class's foo method is causing the exception (nor does the traceback help, since it only shows the item.foo(...) line). Of course, in this example it's easy to see the two classes have foo methods with different signatures, but if there were hundreds of objects in the list and they were instances of dozens of different classes it would be rather more annoying to figure out which class has the incorrect method signature.

    I've looked through the code and the two exceptions above come from the format_missing and too_many_positional functions in Python/ceval.c . It's not obvious how to patch them to use __qualname__ instead of __name__, since they are taking the name from a code object, rather than a function object or bound method object (and code objects don't have an equivalent to __qualname__, only co_name which is related to __name__).

    Several other argument related TypeError exceptions are raised directly in _PyEval_EvalCodeWithName, which does have a qualname parameter, though the function doesn't use it for much. It's also where the other functions described above get called from, so it could probably pass the qualname along to them. Alas, it seems that in some common cases (such as calling a Python function with any kind of argument unpacking like *foo or **foo), the value of the qualname parameter is actually Null, so it may not be of much help.

    A few extra TypeErrors related to function calls are raised directly in the gigantic PyEval_EvalFrameEx function. These seem to all use PyEval_GetFuncName to get the name, so perhaps we could modify its behavior to return the method's __qualname__ rather than the __name__. (I have no idea what backwards compatibility issues this might cause. Perhaps a new function that returns the qualname would be better.)

    @BlckKnght BlckKnght mannequin added the type-feature A feature request or enhancement label Jun 26, 2016
    @vadmium
    Copy link
    Member

    vadmium commented Jun 26, 2016

    Have a look at bpo-2786. I think it might be the same thing.

    @BlckKnght
    Copy link
    Mannequin Author

    BlckKnght mannequin commented Aug 5, 2016

    Yes, this looks to be a duplicate of that issue. I'm closing this issue as a duplicate, but I don't seem to be able to set the Superseder field. If you can, please set that to bpo-2786.

    @BlckKnght BlckKnght mannequin closed this as completed Aug 5, 2016
    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    type-feature A feature request or enhancement
    Projects
    None yet
    Development

    No branches or pull requests

    1 participant