Fix #3539: reload module with assertion rewrite import hook
This commit is contained in:
		
							parent
							
								
									ec57cbf82d
								
							
						
					
					
						commit
						c61ff31ffa
					
				
							
								
								
									
										1
									
								
								AUTHORS
								
								
								
								
							
							
						
						
									
										1
									
								
								AUTHORS
								
								
								
								
							| 
						 | 
					@ -93,6 +93,7 @@ Hui Wang (coldnight)
 | 
				
			||||||
Ian Bicking
 | 
					Ian Bicking
 | 
				
			||||||
Ian Lesperance
 | 
					Ian Lesperance
 | 
				
			||||||
Ionuț Turturică
 | 
					Ionuț Turturică
 | 
				
			||||||
 | 
					Iwan Briquemont
 | 
				
			||||||
Jaap Broekhuizen
 | 
					Jaap Broekhuizen
 | 
				
			||||||
Jan Balster
 | 
					Jan Balster
 | 
				
			||||||
Janne Vanhala
 | 
					Janne Vanhala
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					Fix reload on assertion rewritten modules.
 | 
				
			||||||
| 
						 | 
					@ -269,17 +269,17 @@ class AssertionRewritingHook(object):
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def load_module(self, name):
 | 
					    def load_module(self, name):
 | 
				
			||||||
        # If there is an existing module object named 'fullname' in
 | 
					 | 
				
			||||||
        # sys.modules, the loader must use that existing module. (Otherwise,
 | 
					 | 
				
			||||||
        # the reload() builtin will not work correctly.)
 | 
					 | 
				
			||||||
        if name in sys.modules:
 | 
					 | 
				
			||||||
            return sys.modules[name]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        co, pyc = self.modules.pop(name)
 | 
					        co, pyc = self.modules.pop(name)
 | 
				
			||||||
        # I wish I could just call imp.load_compiled here, but __file__ has to
 | 
					        if name in sys.modules:
 | 
				
			||||||
        # be set properly. In Python 3.2+, this all would be handled correctly
 | 
					            # If there is an existing module object named 'fullname' in
 | 
				
			||||||
        # by load_compiled.
 | 
					            # sys.modules, the loader must use that existing module. (Otherwise,
 | 
				
			||||||
        mod = sys.modules[name] = imp.new_module(name)
 | 
					            # the reload() builtin will not work correctly.)
 | 
				
			||||||
 | 
					            mod = sys.modules[name]
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            # I wish I could just call imp.load_compiled here, but __file__ has to
 | 
				
			||||||
 | 
					            # be set properly. In Python 3.2+, this all would be handled correctly
 | 
				
			||||||
 | 
					            # by load_compiled.
 | 
				
			||||||
 | 
					            mod = sys.modules[name] = imp.new_module(name)
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            mod.__file__ = co.co_filename
 | 
					            mod.__file__ = co.co_filename
 | 
				
			||||||
            # Normally, this attribute is 3.2+.
 | 
					            # Normally, this attribute is 3.2+.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1050,6 +1050,48 @@ class TestAssertionRewriteHookDetails(object):
 | 
				
			||||||
        result = testdir.runpytest("-s")
 | 
					        result = testdir.runpytest("-s")
 | 
				
			||||||
        result.stdout.fnmatch_lines(["* 1 passed*"])
 | 
					        result.stdout.fnmatch_lines(["* 1 passed*"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_reload_reloads(self, testdir):
 | 
				
			||||||
 | 
					        """Reloading a module after change picks up the change."""
 | 
				
			||||||
 | 
					        testdir.tmpdir.join("file.py").write(
 | 
				
			||||||
 | 
					            textwrap.dedent(
 | 
				
			||||||
 | 
					                """
 | 
				
			||||||
 | 
					            def reloaded():
 | 
				
			||||||
 | 
					                return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            def rewrite_self():
 | 
				
			||||||
 | 
					                with open(__file__, 'w') as self:
 | 
				
			||||||
 | 
					                    self.write('def reloaded(): return True')
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        testdir.tmpdir.join("pytest.ini").write(
 | 
				
			||||||
 | 
					            textwrap.dedent(
 | 
				
			||||||
 | 
					                """
 | 
				
			||||||
 | 
					            [pytest]
 | 
				
			||||||
 | 
					            python_files = *.py
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        testdir.makepyfile(
 | 
				
			||||||
 | 
					            test_fun="""
 | 
				
			||||||
 | 
					            import sys
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
 | 
					                from imp import reload
 | 
				
			||||||
 | 
					            except ImportError:
 | 
				
			||||||
 | 
					                pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            def test_loader():
 | 
				
			||||||
 | 
					                import file
 | 
				
			||||||
 | 
					                assert not file.reloaded()
 | 
				
			||||||
 | 
					                file.rewrite_self()
 | 
				
			||||||
 | 
					                reload(file)
 | 
				
			||||||
 | 
					                assert file.reloaded()
 | 
				
			||||||
 | 
					            """
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        result = testdir.runpytest("-s")
 | 
				
			||||||
 | 
					        result.stdout.fnmatch_lines(["* 1 passed*"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_get_data_support(self, testdir):
 | 
					    def test_get_data_support(self, testdir):
 | 
				
			||||||
        """Implement optional PEP302 api (#808).
 | 
					        """Implement optional PEP302 api (#808).
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue