Repository: obspy/obspy

Issue:
inventory.remove() only works for channel-level inventories
```python
from obspy.clients.fdsn import Client
cl = Client('IRIS')
inv = cl.get_stations(network='II,G', level='station')
inv.remove(network='II')
```
gives an empty `Inventory` object.

The same script with `level='channel'` works.


Discussion:
The `Inventory.remove` method is only found in the master branch, bumping to 1.2.0.

Resolving patch:
diff --git a/obspy/core/inventory/inventory.py b/obspy/core/inventory/inventory.py
--- a/obspy/core/inventory/inventory.py
+++ b/obspy/core/inventory/inventory.py
@@ -667,12 +667,14 @@ def remove(self, network='*', station='*', location='*', channel='*',
             without child elements (stations/channels) will still be included
             in the result.
         """
+        # Select all objects that are to be removed.
         selected = self.select(network=network, station=station,
                                location=location, channel=channel)
         selected_networks = [net for net in selected]
         selected_stations = [sta for net in selected_networks for sta in net]
         selected_channels = [cha for net in selected_networks
                              for sta in net for cha in sta]
+        # Iterate inventory tree and rebuild it excluding selected components.
         networks = []
         for net in self:
             if net in selected_networks and station == '*' and \
@@ -688,12 +690,14 @@ def remove(self, network='*', station='*', location='*', channel='*',
                     if cha in selected_channels:
                         continue
                     channels.append(cha)
-                if not channels and not keep_empty:
+                channels_were_empty = not bool(sta.channels)
+                if not channels and not (keep_empty or channels_were_empty):
                     continue
                 sta = copy.copy(sta)
                 sta.channels = channels
                 stations.append(sta)
-            if not stations and not keep_empty:
+            stations_were_empty = not bool(net.stations)
+            if not stations and not (keep_empty or stations_were_empty):
                 continue
             net = copy.copy(net)
             net.stations = stations


Test patch:
diff --git a/obspy/core/tests/test_inventory.py b/obspy/core/tests/test_inventory.py
--- a/obspy/core/tests/test_inventory.py
+++ b/obspy/core/tests/test_inventory.py
@@ -15,6 +15,7 @@
 from future.utils import PY2, native_str
 
 import builtins
+import copy
 import io
 import os
 import unittest
@@ -344,6 +345,27 @@ def test_inventory_remove(self):
             inv_ = inv.remove(**kwargs)
             self.assertEqual(inv_, inv)
 
+    def test_issue_2266(self):
+        """
+        Ensure the remove method works for more than just channel level
+        inventories. See #2266.
+        """
+        # get inventory and remove all channel level info
+        inv = obspy.read_inventory()
+        for net in inv:
+            for sta in net:
+                sta.channels = []
+        # filter by one of the networks
+        inv_net = copy.deepcopy(inv).remove(network='BW')
+        self.assertEqual(len(inv_net.networks), 1)
+        # filter by the stations, this should also remove network BW
+        inv_sta = copy.deepcopy(inv).remove(station='RJOB')
+        self.assertEqual(len(inv_sta.networks), 1)
+        self.assertEqual(len(inv_sta.networks[0].stations), 2)
+        # but is keep empty is selected network BW should remain
+        inv_sta = copy.deepcopy(inv).remove(station='RJOB', keep_empty=True)
+        self.assertEqual(len(inv_sta.networks), 2)
+
     def test_inventory_select(self):
         """
         Test for the Inventory.select() method.
@@ -577,8 +599,8 @@ def test_inventory_can_be_initialized_with_no_arguments(self):
 
 @unittest.skipIf(not BASEMAP_VERSION, 'basemap not installed')
 @unittest.skipIf(
-    BASEMAP_VERSION >= [1, 1, 0] and MATPLOTLIB_VERSION == [3, 0, 1],
-    'matplotlib 3.0.1 is not campatible with basemap')
+    BASEMAP_VERSION or [] >= [1, 1, 0] and MATPLOTLIB_VERSION == [3, 0, 1],
+    'matplotlib 3.0.1 is not compatible with basemap')
 class InventoryBasemapTestCase(unittest.TestCase):
     """
     Tests the for :meth:`~obspy.station.inventory.Inventory.plot` with Basemap.