The reason this happens is that -O0 still invokes a single pass of the "simplifier", which is the optimization pass responsible for, among other things, inlining.
You can't prevent the simplifier from being called, but you can set the number of simplifier iterations to zero, which should cause it to bail out before doing anything:
ghc -O0 -fmax-simplifier-iterations=0 -ddump-simpl
For your handleThing example, this prevents the inlining you've observed.
The inlining that occurs with -O0 is limited to what can be accomplished by inlining fully saturated calls with no eta expansion/reduction. This means that your example:
handleThing = print
{-# INLINE handleThing #-}
main = mapM_ handleThing [1..10]
will inline, but the variation:
handleThing x = print x
{-# INLINE handleThing #-}
main = mapM_ handleThing [1..10]
won't, since the call to handleThing in main is no longer fully saturated.
On the other hand, this will inline both number and handleThing:
number = 10
{-# INLINE number #-}
handleThing x = print x >> print x
{-# INLINE handleThing #-}
main = handleThing number
into main, resulting in:
x = 10
main = >> $fMonadIO (print $fShowInteger x) (print $fShowInteger x)
Here, "inlining" number involves the de-optimization of giving it an extra name and using that.