This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author wolma
Recipients brett.cannon, eric.snow, martin.panter, ncoghlan, wolma
Date 2016-07-13.08:24:30
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1468398271.35.0.252294678744.issue27487@psf.upfronthosting.co.za>
In-reply-to
Content
@Martin and regarding Python3.3: Right, you cannot do the replacement when 
running the module as __main__. For my use case that's not required though so in 
the module I can just do:

if __name__ == '__main__':
    print('running module as a script')
else:
    # do not attempt this when __name__ == '__main__' in Python 3.3
    sys.modules[__name__] = object()
    
Apart from this limitation, such code is compatible with Python 3.2 - 3.5.1, but 
breaks under 3.5.2. It's the fact that it breaks in a maintenance release that 
I find disturbing. In fact, I learnt about the breakage only from an end-user 
who bought a new laptop with OS X, downloaded the latest Python release and 
suddenly could not get our package to run that had worked on his previous 
machine. Turns out, none of our test machines was running 3.5.2 yet, but were 
running 3.5.0 and 3.5.1.

OTOH, I agree with you that the circumstances under which your change causes 
trouble are pretty exotic. As Nick points out, modules replacing themselves in 
sys.modules are not that special. What *makes* the situation special is that 

1) the package __init__.py has to import the self-replacing module and that
2) the self-replacing module is intended to be run via python3 -m package.module

That's why I wrote initially that I don't know if many (or, in fact, any other 
package would be affected by this).

Nick's concern about the double import situation is more general, but since 
this is something earlier releases have been doing, an improvement here would 
be relevant only for a major release (3.6 or 3.7).

Regarding 3.5.3, I'm not sure what the best solution would be:

- the suggestion to copy over the __spec__ attribute to the replacement object 
  is putting the burden on package maintainers. Given that probably only few 
  packages will be affected that may well be acceptable. In fact, for my own 
  case I have now refactored things a bit so I can avoid the import from 
  __init__.py.
  
- from a strict versioning perspective, you may also argue like Nick that if it 
  was working in 3.5.0-1 it should work again in 3.5.3.
  
I'm personally pretty neutral here. I just thought it may be good to report the 
issue so that it becomes easier for others to understand what is going on if 
they encounter the same error. Maybe even the fact that this issue exists now 
is serving this purpose as well as documenting the changed behaviour?
History
Date User Action Args
2016-07-13 08:24:31wolmasetrecipients: + wolma, brett.cannon, ncoghlan, eric.snow, martin.panter
2016-07-13 08:24:31wolmasetmessageid: <1468398271.35.0.252294678744.issue27487@psf.upfronthosting.co.za>
2016-07-13 08:24:31wolmalinkissue27487 messages
2016-07-13 08:24:30wolmacreate