REF: do extract_array earlier in series arith/comparison ops
With this, the middle third of _arith_method_SERIES and _comp_method_SERIES are array-specific and can be refactored out (separate step) to become a) block-wise implementation for DataFrame and b) PandasArray implementation.

This also simplifies the NullFrequencyError handling nicely.
@jreback gentle ping; this turns out to be a blocker(ish) for fixing #28080. Types added Can you expand on `keep_null_freq`? It seems strange to have that specific of an option in a general method like `dispatch_to_extension_op`. When / why do we sometimes convert that to a TypeError? > Can you expand on keep_null_freq? It seems strange to have that specific of an option in a general method like dispatch_to_extension_op. When / why do we sometimes convert that to a TypeError?

If we have a Series that is dt64, dt64tz, or td64, `ser+1` should always raise TypeError.  But because of the way we wrap/unwrap for dispatch_to_extension_op, we end up operating on a DTA/TDA, which will raise NullFrequencyError on `arr+1`.  In these cases we need to catch NullFrequencyError and re-raise as TypeError.

The exception is when we have a Series[int] and we're adding/subtracting a DTA/TDA/DTI/TDI, in which case NullFrequencyError is the correct thing to raise. So the complexity comes from having different rules for `op(Series[datetime], int)` and `op(DatetimeArray, int)`? Can / should we align that behavior instead? > Can / should we align that behavior instead?

The DTA/TDA/DTI/TDI/Timestamp behavior has been deprecated, now just need to be patient So in the future `keep_null_freq` won't be needed? In that case, +1 on the changes here, if we could add a TODO to remove it once the deprecation is enforced. sounds good thanks @jbrockmendel 

yeah the ``keep_null_freq`` stuff is a bit hard to follow, though you have documented it, so I think ok