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

Pass all args to __attrs_pre_init__() #1102

Closed
brendan-simon-indt opened this issue Feb 13, 2023 · 3 comments · Fixed by #1187
Closed

Pass all args to __attrs_pre_init__() #1102

brendan-simon-indt opened this issue Feb 13, 2023 · 3 comments · Fixed by #1187
Labels

Comments

@brendan-simon-indt
Copy link

I am subclassing a class that I have no control over, which is written in standard Python. The base class A has a number of arguments that I want to set. Infact there are 3 classes. C (attrs class) is a sublcass of B (attrs class) which is a subclass of A (non-attrs class).

When I instantiate C, I want to pass arguments to B and A.

I implemented class based factory functions (vai @classmethod), which works well for a single level inheritance, but I'm not sure how to use the classmethod of B from the classmethod of A. I figured I'm stuck with duplicating of the B initialisation within the C classmethod and the instantiating class C by passing all the necessary arguments.

All this involves defining a custom __init__() method (https://www.attrs.org/en/stable/init.html#custom-init), but it seems to me that could be avoided by using __attrs_pre_init__(), but unfortunately it seems no arguments are passed to that (i.e. no *args or **kwargs).

Is there a reason why arguments are not passed to attrs_pre_init__(), and only passed to __init__()?

I think it makes sense to pass all arguments to __attrs_pre_init__() so the user can have the flexibility to do what is required (or nothing at all).

    def __attrs_pre_init__(self, *args, **kwargs):
        ...
        super().__init__(*args, **kwargs)
        ...

I can see why it is less relevant for __attrs_post_init__(), but I'm sure someone can think of a use-case where the arguments could be useful (e.g. for arguments that aren't stored as instanace attributes).

@hynek hynek added the Feature label Mar 11, 2023
@hynek
Copy link
Member

hynek commented Mar 11, 2023

Yeah in hindsight that seems an odd omission. I think the expectation was that you're gonna use a custom init for anything more complicated.

@Tyrubias
Copy link
Contributor

I'm interested in implementing this feature but I'm not sure where to start. I see where the call to __atrs_pre_init__ is being added in src/attr/_make.py. Would I change this call to include the arguments being passed into the __init__ method being generated?

@hynek
Copy link
Member

hynek commented Sep 17, 2023

Without looking closer, I suspect you’ll have to inspect the __attrs_pre_init__ method and call with with or without based on its arguments. For all I care: do nothing if it’s only one argument (presumably self), pass them if it has more than one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants