Repository: PyPSA/PyPSA

Issue:
copying network ignores buses? (master branch)
### Version Checks (indicate both or one)

- [ ] I have confirmed this bug exists on the lastest [release](https://github.com/pypsa/pypsa/releases) of PyPSA.

- [X] I have confirmed this bug exists on the current [`master`](https://github.com/pypsa/pypsa/tree/master) branch of PyPSA.


### Issue Description

When installing the master branch (`pip install git+https://github.com/PyPSA/PyPSA.git@master`) and using `n.copy()`, I'm getting the following warnings:

> WARNING:pypsa.io:The following Generator have buses which are not defined:
> 
> WARNING:pypsa.io:The following Line have buses which are not defined:
> 
> WARNING:pypsa.io:The following Load have buses which are not defined:
> 
> WARNING:pypsa.io:The following StorageUnit have buses which are not defined:

followed by a list of _all_ generators, lines, loads, storage units, respectively

Sometimes links appear, too. My network does not contain stores.  Not sure what's the problem here.

This didn't appear in v0.28.0 (when reverting back with `pip install pypsa==v0.28.0`, everything seems to work as intended - no warnings appear).

Not sure what's the issue, optimization of networks seems work, and all buses seem to exist as intended. The warning is just a bit misleading (and spams the terminal if called often)

### Reproducible Example

```python
import pypsa
n = pypsa.examples.scigrid_de()
n.copy()
```


### Expected Behavior

_No response_

### Installed Versions

<details>

Replace this line.

</details>



Discussion:

Patch:
diff --git a/pypsa/components.py b/pypsa/components.py
index 505410e29..1424d2113 100644
--- a/pypsa/components.py
+++ b/pypsa/components.py
@@ -1083,6 +1083,11 @@ def copy(
 
         """
 
+        # Use copy.deepcopy if no arguments are passed
+        args = [snapshots, investment_periods, ignore_standard_types, with_time]
+        if all(arg is None or arg is False for arg in args):
+            return copy.deepcopy(self)
+
         # Set default arguments
         if snapshots is None:
             snapshots = self.snapshots
@@ -1107,11 +1112,6 @@ def copy(
                 stacklevel=2,
             )
 
-        # Use copy.deepcopy if no arguments are passed
-        args = [snapshots, investment_periods, ignore_standard_types, with_time]
-        if all(arg is None or arg is False for arg in args):
-            return copy.deepcopy(self)
-
         # Setup new network
         (
             override_components,
@@ -1125,7 +1125,9 @@ def copy(
         )
 
         # Copy components
-        for component in self.iterate_components(self.all_components):
+        other_comps = sorted(self.all_components - {"Bus", "Carrier"})
+        # Needs to copy buses and carriers first, since there are dependencies on them
+        for component in self.iterate_components(["Bus", "Carrier"] + other_comps):
             # Drop the standard types to avoid them being read in twice
             if (
                 not ignore_standard_types


Test patch:
diff --git a/test/conftest.py b/test/conftest.py
index 30e207f4a..07b4458d9 100644
--- a/test/conftest.py
+++ b/test/conftest.py
@@ -123,10 +123,10 @@ def all_networks(
 ):
     return [
         ac_dc_network,
-        # ac_dc_network_r,
-        # ac_dc_network_multiindexed,
-        # ac_dc_network_shapes,
-        # storage_hvdc_network,
+        ac_dc_network_r,
+        ac_dc_network_multiindexed,
+        ac_dc_network_shapes,
+        storage_hvdc_network,
     ]
 
 
diff --git a/test/test_lopf_global_constraints.py b/test/test_lopf_global_constraints.py
index 52908cf69..d72112ddd 100644
--- a/test/test_lopf_global_constraints.py
+++ b/test/test_lopf_global_constraints.py
@@ -5,7 +5,7 @@
 
 
 def test_operational_limit_ac_dc_meshed(ac_dc_network):
-    n = ac_dc_network
+    n = ac_dc_network.copy()
 
     limit = 30_000
 
@@ -25,7 +25,7 @@ def test_operational_limit_ac_dc_meshed(ac_dc_network):
 
 
 def test_operational_limit_storage_hvdc(storage_hvdc_network):
-    n = storage_hvdc_network
+    n = storage_hvdc_network.copy()
 
     limit = 5_000