I don't know much about the history either, but under PEP 3147, there
are really two cases:
* .pyc and .pyo as compilation caches. These live in __pycache__/ and
have a cache_tag, their filename looks like
pkg/__pycache__/module.cpython-33.pyc and their only role is to speed up
imports.
* .pyc and .pyo as standalone, precompiled sources for modules. These
are found in the same place as .py files (e.g. pkg/module.pyc).
In the first case, I think that -O should dictate which of .pyc and .pyo
is used, while the other is completely ignored.
In the second case, both .pyc and .pyo should always be considered as
valid module sources, because -O is a compilation flag and loading a
bytecode file doesn't involve compilation. At most, -O could switch the
priority between .pyc and .pyo.
2.7 doesn't really differentiate between cached .pyc and
standalone .pyc, so I don't know if a consistent behaviour can be
achieved. Maybe the presence or absence of a matching .py can be used to
trigger the first or second case above.
http://bugs.python.org/issue12982
Currently, cpython requires the -O flag to *read* .pyo files as well as the write them. This is a nuisance to people who receive them from others, without the source. The originator of the issue quotes the following from the doc (without giving the location).
"It is possible to have a file called spam.pyc (or spam.pyo when -O is used) without a file spam.py for the same module. This can be used to distribute a library of Python code in a form that is moderately hard to reverse engineer."
There is no warning that .pyo files are viral, in a sense. The user has to use -O, which is a) a nuisance to remember if he has multiple scripts and some need it and some not, and b) makes his own .py files used with .pyo imports cached as .pyo, without docstrings, like it or not.
Currently, the easiest workaround is to rename .pyo to .pyc and all seems to work fine, even with a mixture of true .pyc and renamed .pyo files. (The same is true with the -O flag and no renaming.) This suggests that there is no current reason for the restriction in that the *execution* of bytecode is not affected by the -O flag. (Another workaround might be a custom importer -- but this is not trivial, apparently.)
So is the import restriction either an accident or obsolete holdover?
If so, can removing it be treated as a bugfix and put into current releases, or should it be treated as an enhancement only for a future release?
Or is the restriction an intentional reservation of the possibility of making *execution* depend on the flag? Which would mean that the restriction should be kept and only the doc changed?
On Wed, 13 Jun 2012 20:46:50 +0200, Antoine Pitrou <soli...@pitrou.net> wrote:Again, a program that depends on asserts is buggy.
> On Wed, 13 Jun 2012 11:20:24 -0700
> Toshio Kuratomi <a.ba...@gmail.com> wrote:
> > On Wed, Jun 13, 2012 at 01:58:10PM -0400, R. David Murray wrote:
> > >
> > > OK, but you didn't answer the question :). If I understand correctly,
> > > everything you said applies to *writing* the bytecode, not reading it.
> > >
> > > So, is there any reason to not use the .pyo file (if that's all that is
> > > around) when -O is not specified?
> > >
> > > The only technical reason I can see why -O should be required for a .pyo
> > > file to be used (*if* it is the only thing around) is if it won't *run*
> > > without the -O switch. Is there any expectation that that will ever be
> > > the case?
> > >
> > Yes. For instance, if I create a .pyo with -OO it wouldn't have docstrings.
> > Another piece of code can legally import that and try to use the docstring
> > for something. This would fail if only the .pyo was present.
>
> Not only docstrings, but also asserts. I think running a pyo without -O
> would be a bug.
As Ethan pointed out we are asking about the case where someone is
*deliberately* setting the .pyo file up to be run as the "normal"
case.
I'm not sure we want to support that, I just want us to be clear
about why we don't :)
On Thu, 14 Jun 2012 11:48:08 +1000, Nick Coghlan <ncog...@gmail.com> wrote:OK, the above are the two concrete reasons I have heard in this thread
> On Thu, Jun 14, 2012 at 6:06 AM, Terry Reedy <tjr...@udel.edu> wrote:
> > On 6/13/2012 2:46 PM, Antoine Pitrou wrote:
> >
> >> Not only docstrings, but also asserts. I think running a pyo without -O
> >> would be a bug.
> >
> > That cat is already out of the bag ;-)
> > People are doing that now by renaming x.pyo to x.pyc.
> > Brett claims that it is also easy to do in 3.3 with a custom importer.
>
> Right, but by resorting to either of those approaches, people are
> clearly doing something that isn't formally supported by the core.
> Yes, you can do it, and most of the time it will work out OK, but any
> weird glitches that result are officially *not our problem*.
>
> The main reason this matters is that the "__debug__" flag is
> *supposed* to be process global - if you check it in one place, the
for continuing the current behavior:
1) we do not wish to support running from .pyo files without -O
being on, even if it currently happens to work
2) the __debug__ setting is supposed to be process-global
Both of these are good reasons. IMO the issue should be closed with a
documentation fix, which could optionally include either or both of the
above motivations.
> I don't really see the point. In my experience there is no benefit toIt's not at all C specific. C# also has it:
> removing assert statements in production mode. This is a C-specific
> notion that doesn't really map very well to Python code. Do other
> high-level languages have similar functionality?
http://msdn.microsoft.com/en-us/library/ttcc4x86(v=vs.80).aspx
Java makes it a VM option (rather than a compiler option), but it's
still a flag to the VM (-enableassertions):
http://docs.oracle.com/javase/1.4.2/docs/tooldocs/windows/java.html
Delphi also has assertions that can be disabled at compile time.