Repository: NeurodataWithoutBorders/pynwb

Issue:
[Bug]: `add_data_interface` fails silently on pynwb 3.0
### What happened?

It seems that now in pynwb 3.0 the method `add_data_interface` was replaced by `add`.
But the method `add_data_interface` does not add the structure or throws an error. 

### Steps to Reproduce

```python
from pynwb.testing.mock.file import mock_NWBFile
from pynwb.testing.mock.ecephys import mock_ElectricalSeries


nwbfile = mock_NWBFile()

# Create processing modules
ecephys_module = nwbfile.create_processing_module('ecephys', 'Example ecephys data')

electrical_series = mock_ElectricalSeries()
ecephys_module.add_data_interface(electrical_series)

assert len(nwbfile.processing["ecephys"].data_interfaces) == 1
```



- [x] I agree to follow this project's [Code of Conduct](https://github.com/NeurodataWithoutBorders/pynwb/blob/dev/.github/CODE_OF_CONDUCT.rst)
- [x] Have you checked the [Contributing](https://github.com/NeurodataWithoutBorders/pynwb/blob/dev/docs/CONTRIBUTING.rst) document?
- [x] Have you ensured this bug was not already [reported](https://github.com/NeurodataWithoutBorders/pynwb/issues)?

Discussion hints:
codecov[bot]: ## [Codecov](https://app.codecov.io/gh/NeurodataWithoutBorders/pynwb/pull/2052?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NeurodataWithoutBorders) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 82.72%. Comparing base [(`01d9ab9`)](https://app.codecov.io/gh/NeurodataWithoutBorders/pynwb/commit/01d9ab92de25dcd465cfad6d68d9df54679ea54f?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NeurodataWithoutBorders) to head [(`f63fe21`)](https://app.codecov.io/gh/NeurodataWithoutBorders/pynwb/commit/f63fe211c6efc533a3a12edeb21cefdb3fc34601?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NeurodataWithoutBorders).

> :exclamation:  There is a different number of reports uploaded between BASE (01d9ab9) and HEAD (f63fe21). Click for more details.
> 
> <details><summary>HEAD has 15 uploads less than BASE</summary>
>
>| Flag | BASE (01d9ab9) | HEAD (f63fe21) |
>|------|------|------|
>|unit|8|1|
>|integration|8|0|
></details>

<details><summary>Additional details and impacted files</summary>


```diff
@@             Coverage Diff             @@
##              dev    #2052       +/-   ##
===========================================
- Coverage   92.84%   82.72%   -10.13%     
===========================================
  Files          28       28               
  Lines        2755     2756        +1     
  Branches      716      716               
===========================================
- Hits         2558     2280      -278     
- Misses        127      376      +249     
- Partials       70      100       +30     
```

| [Flag](https://app.codecov.io/gh/NeurodataWithoutBorders/pynwb/pull/2052/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NeurodataWithoutBorders) | Coverage Δ | |
|---|---|---|
| [integration](https://app.codecov.io/gh/NeurodataWithoutBorders/pynwb/pull/2052/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NeurodataWithoutBorders) | `?` | |
| [unit](https://app.codecov.io/gh/NeurodataWithoutBorders/pynwb/pull/2052/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NeurodataWithoutBorders) | `82.72% <100.00%> (-0.04%)` | :arrow_down: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NeurodataWithoutBorders#carryforward-flags-in-the-pull-request-comment) to find out more.

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/NeurodataWithoutBorders/pynwb/pull/2052?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NeurodataWithoutBorders).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NeurodataWithoutBorders).


Solution patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3de5f592..c1430ea4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,10 @@
 # PyNWB Changelog
 
+## Upcoming
+
+### Bug fixes
+- Fix `add_data_interface` functionality that was mistakenly removed in PyNWB 3.0. @stephprince [#2052](https://github.com/NeurodataWithoutBorders/pynwb/pull/2052)
+
 ## PyNWB 3.0.0 (February 26, 2025)
 
 ### Breaking changes
diff --git a/src/pynwb/base.py b/src/pynwb/base.py
index e639eccf..a7154450 100644
--- a/src/pynwb/base.py
+++ b/src/pynwb/base.py
@@ -77,6 +77,7 @@ class ProcessingModule(MultiContainerInterface):
              'doc': 'the NWBDataInterface to add to this Module'})
     def add_data_interface(self, **kwargs):
         warn('add_data_interface is deprecated and will be removed in PyNWB 4.0. Use add instead.', DeprecationWarning)
+        self.add(kwargs['NWBDataInterface'])
 
     @docval({'name': 'data_interface_name', 'type': str, 'doc': 'the name of the NWBContainer to retrieve'})
     def get_data_interface(self, **kwargs):


Test patch:
diff --git a/tests/unit/test_base.py b/tests/unit/test_base.py
index aa64d63d..c75ba1e2 100644
--- a/tests/unit/test_base.py
+++ b/tests/unit/test_base.py
@@ -50,6 +50,8 @@ class TestProcessingModule(TestCase):
                                   exc_msg=msg
         ):
             self.pm.add_data_interface(ts)
+            self.assertIn(ts.name, self.pm.containers)
+            self.assertIs(ts, self.pm.containers[ts.name])
 
     def test_deprecated_add_container(self):
         ts = self._create_time_series()
@@ -58,6 +60,8 @@ class TestProcessingModule(TestCase):
                                   exc_msg=msg
         ):
             self.pm.add_container(ts)
+            self.assertIn(ts.name, self.pm.containers)
+            self.assertIs(ts, self.pm.containers[ts.name])
 
     def test_get_data_interface(self):
         """Test adding a data interface to a ProcessingModule and retrieving it using get(...)."""