The manual references these values being set, not just declared, so maybe should check for invisible_p?
Noticeable for example because this works: $ set +o posix; f() { local POSIXLY_CORRECT=; shopt -p -o posix; }; f; shopt -p -o posix set -o posix set +o posix But the opposite does not: $ set -o posix; f() { local POSIXLY_CORRECT; shopt -p -o posix; }; f; shopt -p -o posix set -o posix set -o posix