Language.factory cannot be a subclass without nlp, name args
- Dominant language
- Python
- Stars
- 33.9k
- Forks
- 4.7k
- Avg merge
- 3m
- Merged PRs (30d)
- 1
Description
## How to reproduce the behaviour
Try to import/loading `SubClass` in this example.
```python
from dataclasses import dataclass
from spacy import Language
@dataclass
class SuperClass:
nlp: Language
name: str
@Language.factory("dummy")
class SubClass(SuperClass):
def __init__(self, *args, sub_arg: bool = True):
super().__init__(*args)
self.sub_arg = sub_arg
```
This will lead to the following error
```
File "dummy.py", line 13, in
class SubClass(SuperClass):
File "spacy\language.py", line 490, in add_factory
raise ValueError(Errors.E964.format(name=name))
ValueError: [E964] The pipeline component factory for 'dummy' needs to have the following named arguments, which are passed in by spaCy:
- nlp: receives the current nlp object and lets you access the vocab
- name: the name of the component instance, can be used to identify the component, output losses etc.
```
However, from the surface it would seem that this should just work: ultimately, SubClass does require `nlp` and `name` through its super `SuperClass`. The reason that this errors, to me, is [`get_arg_names`](https://github.com/explosion/spaCy/blob/ca54de27bb5c8fa1579e0730a576b60e153f8a8e/spacy/util.py#L1476-L1484) which only retrieves the arguments for the current class - not its tree.
We could solve this by collecting _all_ args by traversing the class's `__mro__`. This, for instance, does work:
```python
param_names = []
for cls in SubClass.__mro__:
param_names += inspect.signature(cls).parameters.keys()
# ['args', 'sub_arg', 'nlp', 'name']
```
## Your Environment
## Info about spaCy
- **spaCy version:** 3.2.4
- **Platform:** Windows-10-10.0.19041-SP0
- **Python version:** 3.8.8
Contributor guide
Assessment
This issue has not been assessed yet.