As I understand this, there's an exception to the doc snippet in my question. The snippet was:
If a sigspec is RETURN, the command arg is executed each time a shell
function or a script executed with the . or source builtins finishes
executing.
The exception is described here:
All other aspects of the shell execution environment are identical
between a function and its caller with these exceptions: the DEBUG and
RETURN traps (see the description of the trap builtin under SHELL
BUILTIN COMMANDS below) are not inherited unless the function has
been given the trace attribute (see the description of the declare
builtin below) or the -o functrace shell option has been enabled with
the set builtin (in which case all functions inherit the DEBUG and
RETURN traps), and the ERR trap is not inherited unless the -o
errtrace shell option has been enabled.
As for functrace, it can be turned on with the typeset's -t:
-t Give each name the trace attribute. Traced functions inherit the DEBUG and RETURN traps from the calling shell. The trace
attribute has no special meaning for variables.
Also set -o functrace does the trick.
Here's an illustration.
$ trap 'echo ko' RETURN
$ f () { echo ok; }
$ cat y
f
$ . y
ok
ko
$ set -o functrace
$ . y
ok
ko
ko
As for declare, it's the -t option again:
-t Give each name the trace attribute. Traced functions inherit the DEBUG and RETURN traps from the calling shell. The trace
attribute has no special meaning for variables.
Also extdebug enables function tracing, as in ikkachu's answer.
.orsourcecontext. In your example, it works as expected. Callingfalone not trigger the trap.xcontainsfthen the trap should fire up twice?.orsource