Inconsistent behaviour when using `from_pretrained` inside Python classes
Author: I-Absolutely-Am-Not-A-Robot
Pull request: no
Labels: name: bug

### System Info

- `transformers` version: 5.4.0
- Platform: Linux-6.17.0-35-generic-x86_64-with-glibc2.39
- Python version: 3.14.3
- Huggingface_hub version: 1.7.1
- Safetensors version: 0.7.0
- Accelerate version: 1.14.0
- Accelerate config:    not found
- DeepSpeed version: not installed
- PyTorch version (accelerator?): 2.10.0+cu126 (CUDA)
- Using distributed or parallel set-up in script?: _No_
- Using GPU in script?: _No_
- GPU type: NVIDIA GeForce RTX 3080 Ti

### Who can help?

@zucchini-nlp @CyrilVallez

### Information

- [x] The official example scripts
- [x] My own modified scripts

### Tasks

- [ ] An officially supported task in the `examples` folder (such as GLUE/SQuAD, ...)
- [x] My own task or dataset (give details below)

### Reproduction

Libraries needed :
```python
from transformers import MaskFormerImageProcessor, MaskFormerForInstanceSegmentation

import torch.nn as nn
from dataclasses import dataclass
```

Define the checkpoint name for simplicity :
```python 
checkpoint = "facebook/maskformer-swin-small-coco"
```
\
The following scripts all behave differently :

* Default class initialization
```python
class foo():
    def __init__(self):
        self.model = MaskFormerForInstanceSegmentation.from_pretrained(checkpoint)

p = foo()
print(p.model)
# Returns MaskFormerForInstanceSegmentation(...
```

* With `__post_init__`
```python
class foo():
    def __init__(self):
        self.model = None

    def __post_init__(self):
        self.model = MaskFormerForInstanceSegmentation.from_pretrained(checkpoint)

p = foo()
print(p.model)
# Returns None
```
<br><br><br>

* With `@dataclass` decorator
```python
@dataclass
class foo():
    model = None

    def __post_init__(self):
        self.model = MaskFormerForInstanceSegmentation.from_pretrained(checkpoint)

p = foo()
print(p.model)
# Returns MaskFormerForInstanceSegmentation(...
```

* When instanced from `object`
```python
@dataclass
class foo(object):
    model = None

    def __post_init__(self):
        self.model = MaskFormerForInstanceSegmentation.from_pretrained(checkpoint)

p = foo()
print(p.model)
# Returns MaskFormerForInstanceSegmentation(...
```

* When instanced from `nn.Module`
```python
@dataclass
class foo(nn.Module):
    model = None

    def __post_init__(self):
        super().__init__()

        self.model = MaskFormerForInstanceSegmentation.from_pretrained(checkpoint)

p = foo()
print(p.model)
# Returns None
```
<br>

* When using `MaskFormerImageProcessor` instead of `MaskFormerForInstanceSegmentation`
```python
@dataclass
class foo(nn.Module):
    model = None

    def __post_init__(self):
        super().__init__()
        
        self.model = MaskFormerImageProcessor.from_pretrained(checkpoint)

p = foo()
print(p.model)
# Returns MaskFormerImageProcessor {...
```

### Expected behavior

I expected the model to be fetched correctly using the `from_pretrained` method of `MaskFormerForInstanceSegmentation` regardless of whether the model was inside a class or not.

I believe this issue is related to this one #42418 since the `__post_init__` call seems to be the culprit here.

N.B.: This is my first **real** issue on this repo (and GitHub! 🥳 ) so apologies if this was already brought up before (~and pardon any misuse of the english language, I'm not a native speaker 🫠~ ) 

Comments:
I don't understand the issue

You are trying to trigger `__post_init__` to execute which you successfully achieve by adding a dataclass decorator. Without a decoratort it won't call `__post_init__` unless you do so manually at the end of your `cls.__init__`

In any case, not related to transformers and `from_pretrained`, so I will close this issue

Yeah, this is just a simple Python bug in your code, sorry! `__post_init__()` is not called by default in Python objects, so that code will be ignored unless your `__init__()` calls it explicitly, or you inherit from a class that calls it in its `__init__()`. Also, `@dataclass` creates a new class and adds/overrides methods on the decorated class, so combining it with `nn.Module` will create a hybrid class whose behaviour will be determined by whichever methods survive the merge.

The issue actually has nothing to do with `from_pretrained()` - exactly the same pattern should occur if you just do `self.model = 'foo'` or something.

First of all, thank you for taking the time to reply, it means a lot 🙏 

> I don't understand the issue

My apologies, I should have been more explicit : the issue I was referring to was the last two examples where the `from_trained` call from `MaskFormerForInstanceSegmentation` returns `None` while the `from_trained` call from `MaskFormerImageProcessor` returns a successful instance.
I do know that both classes don't return the same type of object, I was just surprised that the `from_trained` call differed greatly.

> `__post_init__()` is not called by default in Python objects, so that code will be ignored unless your `__init__()` calls it explicitly, or you inherit from a class that calls it in its `__init__()`.

Agreed, `__post_init__` is not implicitly called, unless `def`'d by the user

IIRC, `@dataclass` first calls `__init__` then `__post_init__` in that order if they've already been explicitly defined, and if not, it will automatically define a constructor with the user-defined fields just under the `class` keyword.

The different code snippets where for testing different init methods to sort of ""mess up"" calls to `__post_init__` inside the `MaskFormerForInstanceSegmentation` object if there's any to make sure it behaves correctly.
 
<br>

**EDIT**: I may be dumb, because it may have to do with the fact that `nn.Module`s must be correctly initialized before, hence the mandatory call to `super().__init__()`...   

<img width="817" height="374" alt="Image" src="https://github.com/user-attachments/assets/52ab8cd9-f11e-432e-a990-ef6500e0a30f" />


Yeah, that is prob due ot nn.Module and dataclass interacting in weird way. The `model` in your example is a bare processor, while `model2` is an actual model that inherits from `nn.Module` and thus isn't being loaded somehow

I recommend to see how `nn.Module` and dataclass interactions have to be handled in their docs, if there's anything. You can verufy that the loading happens correctly, so it is rather a bug with assigning a model to `self.model`

```
from transformers import MaskFormerImageProcessor, MaskFormerForInstanceSegmentation

import torch.nn as nn
from dataclasses import dataclass

checkpoint = "facebook/maskformer-swin-small-coco"

@dataclass
class foo(nn.Module):
    model: MaskFormerForInstanceSegmentation | None = None
    processor: MaskFormerImageProcessor | None = None

    def __post_init__(self):
        super().__init__()
        
        self.processor = MaskFormerImageProcessor.from_pretrained(checkpoint)
        model = MaskFormerForInstanceSegmentation.from_pretrained(checkpoint)
        print('loaded but not assigned yet', type(model))
        self.model = model # assign a dataclass field

p = foo()
print(type(p.model))

```