[Python-Dev] Criticism of execfile() removal in Python3

Terry Reedy tjreedy at udel.edu
Tue Jun 10 05:56:09 CEST 2014


On 6/9/2014 11:03 PM, Steven D'Aprano wrote:
> On Tue, Jun 10, 2014 at 05:23:12AM +0300, Paul Sokolovsky wrote:
>
>> execfile() builtin function was removed in 3.0.

Because it was hardly ever used. For short bits of code, it is usually 
inferior to exec with a string in the file. For substantial bits of 
code, it is generally inferior to 'from file import *' and does not have 
the option of other forms of import. For startup code that you want 
every session, it is inferior to PYTHONSTARTUP or custom site module.

 >> This brings few problems:
>> 1. It hampers interactive mode - instead of short and easy to type
>> execfile("file.py") one needs to use exec(open("file.py").read())

> If the amount of typing is the problem, that's easy to solve:
>
> # do this once
> def execfile(name):
>      exec(open("file.py").read())
>
> Another possibility is:
>
> os.system("python file.py")
>
>
>> 2. Ok, assuming that exec(open().read()) idiom is still a way to go,
>> there's a problem - it requires to load entire file to memory. But
>> there can be not enough memory. Consider 1Mb file with 900Kb comments
>> (autogenerated, for example). execfile() could easily parse it, using
>> small buffer. But exec() requires to slurp entire file into memory, and
>> 1Mb is much more than heap sizes that we target.

Execfile could slurp the whole file into memory too. Next parse the 
entire file. Then execute the entire bytecode. Finally toss the bytecode 
so that the file has to be reparsed next time it is used.

> There's nothing stopping alternative implementations having their own
> implementation-specific standard library modules.
...
> So you could do this:
>
> from upy import execfile
> execfile("file.py")
>
> So long as you make it clear that this is a platform specific module,
> and don't advertise it as a language feature, I see no reason why you
> cannot do that.

If you want execfile as a substitute for 'python -i file' on the 
unavailable command console, you should have the option to restore 
globals to initial condition. Something like (untested)

# startup entries in globals in CPython 3.4.1
startnames={'__spec__', '__name__', '__builtins__',
         '__doc__', '__loader__', '__package__'}

def execfile(file, encoding='utf-8', restart=<True/False>):
   glodict = globals()
   code = open(file, 'r', encoding=encoding)
   # don't restart if the file does not open
   if restart:
     for name in list(glodict):
       if name not in startnames:
          del glodict(name)
   for statement in statements(code):  # statements is statement iterator
     exec(statement,...globals=glodict, locals=glodict)

-- 
Terry Jan Reedy



More information about the Python-Dev mailing list