(component_func: PipeCallable)
| 587 | component_name = name if name is not None else util.get_object_name(func) |
| 588 | |
| 589 | def add_component(component_func: PipeCallable) -> Callable: |
| 590 | if isinstance(func, type): # function is a class |
| 591 | raise ValueError(Errors.E965.format(name=component_name)) |
| 592 | |
| 593 | def factory_func(nlp, name: str) -> PipeCallable: |
| 594 | return component_func |
| 595 | |
| 596 | internal_name = cls.get_factory_name(name) |
| 597 | if internal_name in registry.factories: |
| 598 | # We only check for the internal name here – it's okay if it's a |
| 599 | # subclass and the base class has a factory of the same name. We |
| 600 | # also only raise if the function is different to prevent raising |
| 601 | # if module is reloaded. It's hacky, but we need to check the |
| 602 | # existing functure for a closure and whether that's identical |
| 603 | # to the component function (because factory_func created above |
| 604 | # will always be different, even for the same function) |
| 605 | existing_func = registry.factories.get(internal_name) |
| 606 | closure = existing_func.__closure__ |
| 607 | wrapped = [c.cell_contents for c in closure][0] if closure else None |
| 608 | if util.is_same_func(wrapped, component_func): |
| 609 | factory_func = existing_func # noqa: F811 |
| 610 | |
| 611 | cls.factory( |
| 612 | component_name, |
| 613 | assigns=assigns, |
| 614 | requires=requires, |
| 615 | retokenizes=retokenizes, |
| 616 | func=factory_func, |
| 617 | ) |
| 618 | return component_func |
| 619 | |
| 620 | if func is not None: # Support non-decorator use cases |
| 621 | return add_component(func) |
nothing calls this directly
no test coverage detected