nedbat / cog

Small bits of Python computation for static files
MIT License
340 stars 26 forks source link

Most recent Python updates break -I parameter #16

Closed bnavigator closed 3 years ago

bnavigator commented 3 years ago

With the most recent Python 3.9.5, 3.8.10 fixing bpo-43105, cogapp can no longer import modules from relative paths given by -I.

Test failures:

[   31s] ============================= test session starts ==============================
[   31s] platform linux -- Python 3.9.5, pytest-6.2.2, py-1.10.0, pluggy-0.13.1
[   31s] rootdir: /home/abuild/rpmbuild/BUILD/cogapp-3.0.0, configfile: setup.cfg
[   31s] collected 130 items
[   31s] 
[   32s] cogapp/test_cogapp.py .................................................. [ 38%]
[   32s] ............................FFF...............................           [ 86%]
[   32s] cogapp/test_makefiles.py .....                                           [ 90%]
[   33s] cogapp/test_whiteutils.py .............                                  [100%]
[   33s] 
[   33s] =================================== FAILURES ===================================
[   33s] _____________________ CogIncludeTests.testTwoIncludePaths ______________________
[   33s] 
[   33s] self = <cogapp.test_cogapp.CogIncludeTests testMethod=testTwoIncludePaths>
[   33s] 
[   33s]     def testTwoIncludePaths(self):
[   33s]         # Test that two -I's add include directories properly.
[   33s]         makeFiles(self.dincludes)
[   33s]         self.cog.callableMain(['argv0', '-r', '-I', 'include', '-I', 'inc2', 'test.cog'])
[   33s] >       self.assertFilesSame('test.cog', 'test.out')
[   33s] 
[   33s] cogapp/test_cogapp.py:1551: 
[   33s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[   33s] cogapp/test_cogapp.py:791: in assertFilesSame
[   33s]     self.assertEqual(text1, text2)
[   33s] E   AssertionError: b'//[[15 chars]rt mymodule\n//]]]\nHello from mymodule in inc2\n//[[[end]]]\n' != b'//[[15 chars]rt mymodule\n//]]]\nHello from mymodule\n//[[[end]]]\n'
[   33s] _____________________ CogIncludeTests.testTwoIncludePaths2 _____________________
[   33s] 
[   33s] self = <cogapp.cogapp.CogGenerator object at 0x7fc50518a1c0>
[   33s] cog = <cogapp.cogapp.Cog object at 0x7fc50518a460>
[   33s] globals = {'__builtins__': {'ArithmeticError': <class 'ArithmeticError'>, 'AssertionError': <class 'AssertionError'>, 'AttributeError': <class 'AttributeError'>, 'BaseException': <class 'BaseException'>, ...}, 'cog': <module 'cog'>}
[   33s] fname = '<cog test.cog:1>'
[   33s] 
[   33s]     def evaluate(self, cog, globals, fname):
[   33s]         # figure out the right whitespace prefix for the output
[   33s]         prefOut = whitePrefix(self.markers)
[   33s]     
[   33s]         intext = self.getCode()
[   33s]         if not intext:
[   33s]             return ''
[   33s]     
[   33s]         prologue = "import " + cog.cogmodulename + " as cog\n"
[   33s]         if self.options.sPrologue:
[   33s]             prologue += self.options.sPrologue + '\n'
[   33s]         code = compile(prologue + intext, str(fname), 'exec')
[   33s]     
[   33s]         # Make sure the "cog" module has our state.
[   33s]         cog.cogmodule.msg = self.msg
[   33s]         cog.cogmodule.out = self.out
[   33s]         cog.cogmodule.outl = self.outl
[   33s]         cog.cogmodule.error = self.error
[   33s]     
[   33s]         self.outstring = ''
[   33s]         try:
[   33s] >           eval(code, globals)
[   33s] 
[   33s] cogapp/cogapp.py:169: 
[   33s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[   33s] 
[   33s] >   ???
[   33s] E   ModuleNotFoundError: No module named 'mymodule'
[   33s] 
[   33s] <cog test.cog:1>:2: ModuleNotFoundError
[   33s] 
[   33s] During handling of the above exception, another exception occurred:
[   33s] 
[   33s] self = <cogapp.test_cogapp.CogIncludeTests testMethod=testTwoIncludePaths2>
[   33s] 
[   33s]     def testTwoIncludePaths2(self):
[   33s]         # Test that two -I's add include directories properly.
[   33s]         makeFiles(self.dincludes)
[   33s] >       self.cog.callableMain(['argv0', '-r', '-I', 'inc2', '-I', 'include', 'test.cog'])
[   33s] 
[   33s] cogapp/test_cogapp.py:1556: 
[   33s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[   33s] cogapp/cogapp.py:751: in callableMain
[   33s]     self.processArguments([a])
[   33s] cogapp/cogapp.py:725: in processArguments
[   33s]     self.processWildcards(args[0])
[   33s] cogapp/cogapp.py:690: in processWildcards
[   33s]     self.processOneFile(sMatchingFile)
[   33s] cogapp/cogapp.py:666: in processOneFile
[   33s]     sNewText = self.processString(sOldText, fname=sFile)
[   33s] cogapp/cogapp.py:605: in processString
[   33s]     self.processFile(fOld, fNew, fname=fname)
[   33s] cogapp/cogapp.py:545: in processFile
[   33s]     sGen = gen.evaluate(cog=self, globals=globals, fname=sFile)
[   33s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[   33s] 
[   33s] self = <cogapp.cogapp.CogGenerator object at 0x7fc50518a1c0>
[   33s] cog = <cogapp.cogapp.Cog object at 0x7fc50518a460>
[   33s] globals = {'__builtins__': {'ArithmeticError': <class 'ArithmeticError'>, 'AssertionError': <class 'AssertionError'>, 'AttributeError': <class 'AttributeError'>, 'BaseException': <class 'BaseException'>, ...}, 'cog': <module 'cog'>}
[   33s] fname = '<cog test.cog:1>'
[   33s] 
[   33s]     def evaluate(self, cog, globals, fname):
[   33s]         # figure out the right whitespace prefix for the output
[   33s]         prefOut = whitePrefix(self.markers)
[   33s]     
[   33s]         intext = self.getCode()
[   33s]         if not intext:
[   33s]             return ''
[   33s]     
[   33s]         prologue = "import " + cog.cogmodulename + " as cog\n"
[   33s]         if self.options.sPrologue:
[   33s]             prologue += self.options.sPrologue + '\n'
[   33s]         code = compile(prologue + intext, str(fname), 'exec')
[   33s]     
[   33s]         # Make sure the "cog" module has our state.
[   33s]         cog.cogmodule.msg = self.msg
[   33s]         cog.cogmodule.out = self.out
[   33s]         cog.cogmodule.outl = self.outl
[   33s]         cog.cogmodule.error = self.error
[   33s]     
[   33s]         self.outstring = ''
[   33s]         try:
[   33s]             eval(code, globals)
[   33s]         except CogError:
[   33s]             raise
[   33s]         except:
[   33s]             typ, err, tb = sys.exc_info()
[   33s]             frames = (tuple(fr) for fr in traceback.extract_tb(tb.tb_next))
[   33s]             frames = find_cog_source(frames, prologue)
[   33s]             msg = "".join(traceback.format_list(frames))
[   33s]             msg += "{}: {}".format(typ.__name__, err)
[   33s] >           raise CogUserException(msg)
[   33s] E           cogapp.cogapp.CogUserException:   File "test.cog", line 2, in <module>
[   33s] E               def func():
[   33s] E           ModuleNotFoundError: No module named 'mymodule'
[   33s] 
[   33s] cogapp/cogapp.py:178: CogUserException
[   33s] ____________________ CogIncludeTests.testUselessIncludePath ____________________
[   33s] 
[   33s] self = <cogapp.cogapp.CogGenerator object at 0x7fc5051515e0>
[   33s] cog = <cogapp.cogapp.Cog object at 0x7fc505151b80>
[   33s] globals = {'__builtins__': {'ArithmeticError': <class 'ArithmeticError'>, 'AssertionError': <class 'AssertionError'>, 'AttributeError': <class 'AttributeError'>, 'BaseException': <class 'BaseException'>, ...}, 'cog': <module 'cog'>}
[   33s] fname = '<cog test.cog:1>'
[   33s] 
[   33s]     def evaluate(self, cog, globals, fname):
[   33s]         # figure out the right whitespace prefix for the output
[   33s]         prefOut = whitePrefix(self.markers)
[   33s]     
[   33s]         intext = self.getCode()
[   33s]         if not intext:
[   33s]             return ''
[   33s]     
[   33s]         prologue = "import " + cog.cogmodulename + " as cog\n"
[   33s]         if self.options.sPrologue:
[   33s]             prologue += self.options.sPrologue + '\n'
[   33s]         code = compile(prologue + intext, str(fname), 'exec')
[   33s]     
[   33s]         # Make sure the "cog" module has our state.
[   33s]         cog.cogmodule.msg = self.msg
[   33s]         cog.cogmodule.out = self.out
[   33s]         cog.cogmodule.outl = self.outl
[   33s]         cog.cogmodule.error = self.error
[   33s]     
[   33s]         self.outstring = ''
[   33s]         try:
[   33s] >           eval(code, globals)
[   33s] 
[   33s] cogapp/cogapp.py:169: 
[   33s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[   33s] 
[   33s] >   ???
[   33s] E   ModuleNotFoundError: No module named 'mymodule'
[   33s] 
[   33s] <cog test.cog:1>:2: ModuleNotFoundError
[   33s] 
[   33s] During handling of the above exception, another exception occurred:
[   33s] 
[   33s] self = <cogapp.test_cogapp.CogIncludeTests testMethod=testUselessIncludePath>
[   33s] 
[   33s]     def testUselessIncludePath(self):
[   33s]         # Test that the search will continue past the first directory.
[   33s]         makeFiles(self.dincludes)
[   33s] >       self.cog.callableMain(['argv0', '-r', '-I', 'inc3', '-I', 'include', 'test.cog'])
[   33s] 
[   33s] cogapp/test_cogapp.py:1562: 
[   33s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[   33s] cogapp/cogapp.py:751: in callableMain
[   33s]     self.processArguments([a])
[   33s] cogapp/cogapp.py:725: in processArguments
[   33s]     self.processWildcards(args[0])
[   33s] cogapp/cogapp.py:690: in processWildcards
[   33s]     self.processOneFile(sMatchingFile)
[   33s] cogapp/cogapp.py:666: in processOneFile
[   33s]     sNewText = self.processString(sOldText, fname=sFile)
[   33s] cogapp/cogapp.py:605: in processString
[   33s]     self.processFile(fOld, fNew, fname=fname)
[   33s] cogapp/cogapp.py:545: in processFile
[   33s]     sGen = gen.evaluate(cog=self, globals=globals, fname=sFile)
[   33s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[   33s] 
[   33s] self = <cogapp.cogapp.CogGenerator object at 0x7fc5051515e0>
[   33s] cog = <cogapp.cogapp.Cog object at 0x7fc505151b80>
[   33s] globals = {'__builtins__': {'ArithmeticError': <class 'ArithmeticError'>, 'AssertionError': <class 'AssertionError'>, 'AttributeError': <class 'AttributeError'>, 'BaseException': <class 'BaseException'>, ...}, 'cog': <module 'cog'>}
[   33s] fname = '<cog test.cog:1>'
[   33s] 
[   33s]     def evaluate(self, cog, globals, fname):
[   33s]         # figure out the right whitespace prefix for the output
[   33s]         prefOut = whitePrefix(self.markers)
[   33s]     
[   33s]         intext = self.getCode()
[   33s]         if not intext:
[   33s]             return ''
[   33s]     
[   33s]         prologue = "import " + cog.cogmodulename + " as cog\n"
[   33s]         if self.options.sPrologue:
[   33s]             prologue += self.options.sPrologue + '\n'
[   33s]         code = compile(prologue + intext, str(fname), 'exec')
[   33s]     
[   33s]         # Make sure the "cog" module has our state.
[   33s]         cog.cogmodule.msg = self.msg
[   33s]         cog.cogmodule.out = self.out
[   33s]         cog.cogmodule.outl = self.outl
[   33s]         cog.cogmodule.error = self.error
[   33s]     
[   33s]         self.outstring = ''
[   33s]         try:
[   33s]             eval(code, globals)
[   33s]         except CogError:
[   33s]             raise
[   33s]         except:
[   33s]             typ, err, tb = sys.exc_info()
[   33s]             frames = (tuple(fr) for fr in traceback.extract_tb(tb.tb_next))
[   33s]             frames = find_cog_source(frames, prologue)
[   33s]             msg = "".join(traceback.format_list(frames))
[   33s]             msg += "{}: {}".format(typ.__name__, err)
[   33s] >           raise CogUserException(msg)
[   33s] E           cogapp.cogapp.CogUserException:   File "test.cog", line 2, in <module>
[   33s] E               def func():
[   33s] E           ModuleNotFoundError: No module named 'mymodule'
[   33s] 
[   33s] cogapp/cogapp.py:178: CogUserException
[   33s] =============================== warnings summary ===============================
[   33s] cogapp/cogapp.py:14
[   33s]   /home/abuild/rpmbuild/BUILD/cogapp-3.0.0/cogapp/cogapp.py:14: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses
[   33s]     import imp
[   33s] 
[   33s] -- Docs: https://docs.pytest.org/en/stable/warnings.html
[   33s] =========================== short test summary info ============================
[   33s] FAILED cogapp/test_cogapp.py::CogIncludeTests::testTwoIncludePaths - Assertio...
[   33s] FAILED cogapp/test_cogapp.py::CogIncludeTests::testTwoIncludePaths2 - cogapp....
[   33s] FAILED cogapp/test_cogapp.py::CogIncludeTests::testUselessIncludePath - cogap...
[   33s] =================== 3 failed, 127 passed, 1 warning in 2.19s ===================

Workaround: Replace https://github.com/nedbat/cog/blob/6cc0fff7d691f97163f1fd8971f2c1ca05337ac3/cogapp/cogapp.py#L307

with

self.addToIncludePath(os.path.abspath(a))
nedbat commented 3 years ago

Thanks, fixed in 01f9ae2.