The standart implementation of python(CPython) compiles the code only to bytecode.
For freeze - It saves the python bytecode as a C array and compile it in exe. then It simply run it by the interpreter.
I guess py2exe use a similar way(as far as I know it does not require compiler).
If you don't want to read this: It still uses the standart interpreter to execute python bytecode. It is not turned into machine code.
Basically if someone decide to read your code or modify it, you cannot stop him. (Even if its in machine code/bytecode)
Also python bytecode keeps variables and function names, so I guess the source can be completely recovered from bytecode(without comments).