Suggested API change  (separate beginning/end from first/last) and simplifications (do away with _check_ba):

```
def connect(callback, before=None, after=None, first=True):
    before = before if isinstance(before, list) else [before]
    after = before if isinstance(after, list) else [after]
    for i, cb in enumerate(self.callbacks):
        if cb in after:
            aidx = i
        if cb in before:
            bidx = min(bidx, i)
    assert aidx < bidx
    index = aidx + 1 if first else bidx
    self.callbacks.insert(index, callback)        
```

So the callback can be added either to the beginning or end of the group between 'before' and 'after'.