API: ops alignment behavior inconsistencies
In both Series and DataFrame ops, we have inconsistent behavior for when we call `self.align` vs when we raise.  Everything discussed here is for non-flex ops.

Case 1: consider `op(ser1, ser2)` for two Series with non-matching indexes.
- arithmetic ops call `self.align(other)`
- comparison ops raise `ValueError("Can only compare identically-labeled Series objects")`
- logical ops call `self.align(other)`

Case 2: consider `op(df1, df2)` for two DataFrames with non-matching axes
- arithmetic ops call `self.align(other)`
- comparison ops raise `ValueError("Can only compare identically-labeled DataFrame objects")`
- logical ops call `self.align(other)`

Case 3) consider `op(df, ser)`.  This always aligns, with comparison not being treated differently from the other two.

The policy (and code) would be simpler if we changed this so that either:
a) the comparison op in case 3 doesn't align, matching cases 1 and 2
b) comparison ops always align, matching arithmetic and logical ops