Skip to content

Exception.__init__.__qualname__ is incorrectly set to 'BaseException.__init__' #2771

Closed

Description

@sobolevn

Feature

CPython:

Python 3.9.4 (default, Apr  5 2021, 01:47:16) 
[Clang 11.0.0 (clang-1100.0.33.17)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> Exception.__init__.__qualname__
'Exception.__init__'

RustPython:

Welcome to the magnificent Rust Python 0.1.2 interpreter 😱 🖖
>>>>> Exception.__init__.__qualname__
'BaseException.__init__'

Activity

  1. sobolevn commented on Aug 1, 2021

    @sobolevn
    ContributorAuthor

    I am working right now on this problem.

    I also need to test this case:

    >>> class S(str):
    ...    ...
    ... 
    >>> S.replace
    <method 'replace' of 'str' objects>
  2. sobolevn commented on Aug 12, 2021

    @sobolevn
    ContributorAuthor

    Currently CPython uses three macros to define different Exception types:

    • SimpleExtendsException
    • MiddlingExtendsException
    • ComplexExtendsException

    These macros copies different parts of BaseException attributes. Like (initproc)BaseException_init for SimpleExtendsException which is the root cause for this specific bugreport.

    I am also planning to write macros to match the CPython implementation.
    Does this sound ok?

  3. youknowone commented on Aug 12, 2021

    @youknowone
    Member

    writing functions to match CPython macros, right?
    I think we already have similar functions.

    adding a doc parameter to create_exception_type will be same as SimpleExtendsException.
    adding a few more for specific usage will be good.

  4. sobolevn commented on Aug 12, 2021

    @sobolevn
    ContributorAuthor

    macros
    functions

    Ok, so, here's my take on this problem.

    While we call create_exception_type all .attributes are not yet set (default is {}). But, we need to copy things like __init__ at some point. The other opportunity is when we call extend_class!, but not all exception types are extended. I don't see any other places where this can be done.

    So, I was planning to replace extend_class! calls here:

    extend_class!(ctx, &excs.syntax_error, {
    "msg" => ctx.new_readonly_getset("msg", excs.syntax_error.clone(), make_arg_getter(0)),
    // TODO: members
    "filename" => ctx.none(),
    "lineno" => ctx.none(),
    "offset" => ctx.none(),
    "text" => ctx.none(),
    });
    extend_class!(ctx, &excs.system_exit, {
    "code" => ctx.new_readonly_getset("code", excs.system_exit.clone(), system_exit_code),
    });
    extend_class!(ctx, &excs.import_error, {
    "__init__" => ctx.new_method("__init__", excs.import_error.clone(), import_error_init),
    "msg" => ctx.new_readonly_getset("msg", excs.import_error.clone(), make_arg_getter(0)),
    });
    extend_class!(ctx, &excs.stop_iteration, {
    "value" => ctx.new_readonly_getset("value", excs.stop_iteration.clone(), make_arg_getter(0)),
    });
    extend_class!(ctx, &excs.key_error, {
    "__str__" => ctx.new_method("__str__", excs.key_error.clone(), key_error_str),
    });
    let errno_getter =
    ctx.new_readonly_getset("errno", excs.os_error.clone(), |exc: PyBaseExceptionRef| {
    let args = exc.args();
    let args = args.as_slice();
    args.get(0).filter(|_| args.len() > 1).cloned()
    });
    #[cfg(windows)]
    extend_class!(ctx, &excs.os_error, {
    // TODO: this isn't really accurate
    "winerror" => errno_getter.clone(),
    });
    extend_class!(ctx, &excs.os_error, {
    "errno" => errno_getter,
    "strerror" => ctx.new_readonly_getset("strerror", excs.os_error.clone(), make_arg_getter(1)),
    });
    extend_class!(ctx, &excs.unicode_decode_error, {
    "encoding" => ctx.new_readonly_getset("encoding", excs.unicode_decode_error.clone(), make_arg_getter(0)),
    "object" => ctx.new_readonly_getset("object", excs.unicode_decode_error.clone(), make_arg_getter(1)),
    "start" => ctx.new_readonly_getset("start", excs.unicode_decode_error.clone(), make_arg_getter(2)),
    "end" => ctx.new_readonly_getset("end", excs.unicode_decode_error.clone(), make_arg_getter(3)),
    "reason" => ctx.new_readonly_getset("reason", excs.unicode_decode_error.clone(), make_arg_getter(4)),
    });
    extend_class!(ctx, &excs.unicode_encode_error, {
    "encoding" => ctx.new_readonly_getset("encoding", excs.unicode_encode_error.clone(), make_arg_getter(0)),
    "object" => ctx.new_readonly_getset("object", excs.unicode_encode_error.clone(), make_arg_getter(1)),
    "start" => ctx.new_readonly_getset("start", excs.unicode_encode_error.clone(), make_arg_getter(2), ),
    "end" => ctx.new_readonly_getset("end", excs.unicode_encode_error.clone(), make_arg_getter(3)),
    "reason" => ctx.new_readonly_getset("reason", excs.unicode_encode_error.clone(), make_arg_getter(4)),
    });
    extend_class!(ctx, &excs.unicode_translate_error, {
    "encoding" => ctx.new_readonly_getset("encoding", excs.unicode_translate_error.clone(), none_getter),
    "object" => ctx.new_readonly_getset("object", excs.unicode_translate_error.clone(), make_arg_getter(0)),
    "start" => ctx.new_readonly_getset("start", excs.unicode_translate_error.clone(), make_arg_getter(1)),
    "end" => ctx.new_readonly_getset("end", excs.unicode_translate_error.clone(), make_arg_getter(2)),
    "reason" => ctx.new_readonly_getset("reason", excs.unicode_translate_error.clone(), make_arg_getter(3)),
    });
    with new macros similar to ones CPython has. I also plan to check that all exceptions from ExceptionZoo are covered by these macroses.

    Thoughts?

  5. youknowone commented on Aug 12, 2021

    @youknowone
    Member

    it seems I didn't catch your idea yet. are you planning to make something like #[pyexception] like #[pyclass]? or richer version of extend_class!?
    If we need them to implement things, we need it. SimpleExtendsException looked like somewhat we already had to me, but maybe i overlooked the features of them.

  6. sobolevn commented on Aug 12, 2021

    @sobolevn
    ContributorAuthor

    or richer version of extend_class!?

    This looks easier and more flexible to me right now.

    I will show you the code soon 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions