Kara-Moon Forum
March 29, 2024, 07:47:23 AM *
Welcome, Guest. Please login or register.

Login with username, password and session length
News: You can go back to the main site here: Kara-Moon site
 
   Home   Help Search Login Register  
Pages: [1]
  Print  
Author Topic: Crash with plugins  (Read 3204 times)
sciurius
Sr. Member
****
Posts: 443



« on: March 07, 2020, 08:03:17 PM »

MMA 20.02, Fedora 31, Python 3.7.6.

Loading modules that use MMA/pluginsUtils.py may crash.

When the module calls setAuthor() or setDescription() and friends, pluginUtils.py calls (internally) _P().

_P() calls _getCallerFileName()

_getCallerFileName() processes all loaded modules, skipping modules that are None or do not have a __file__ attribute.

The __file__ attribute is then compared to the __file__ attribute of the calling module (the plugin). This crashes if the module has a __file__ attribute that is None.

Traceback (most recent call last):
  File "/home/jv/bin/mma", line 78, in <module>
    import MMA.main
  File "/home/jv/lib/mma/MMA/main.py", line 92, in <module>
    MMA.paths.readRC()
  File "/home/jv/lib/mma/MMA/paths.py", line 118, in readRC
    MMA.parse.parseFile(f)
  File "/home/jv/lib/mma/MMA/parse.py", line 91, in parseFile
    parse(f)
  File "/home/jv/lib/mma/MMA/parse.py", line 161, in parse
    simpleFuncs[action](l[1:])
  File "/home/jv/lib/mma/MMA/regplug.py", line 405, in plugin
    registerPlugin(p)
  File "/home/jv/lib/mma/MMA/regplug.py", line 295, in registerPlugin
    e = importlib.import_module(modName, package=None)
  File "/usr/lib64/python3.7/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "/home/jv/lib/mma/plugins/customize/plugin.py", line 11, in <module>
    pu.setDescription("Customize MMA.")
  File "/home/jv/lib/mma/MMA/pluginUtils.py", line 103, in setDescription
    _P().DESCRIPTION = descr
  File "/home/jv/lib/mma/MMA/pluginUtils.py", line 94, in _P
    module = _getCallerModule()
  File "/home/jv/lib/mma/MMA/pluginUtils.py", line 81, in _getCallerModule
    if module.__file__.rpartition(".")[0] != f.rpartition(".")[0]:
AttributeError: 'NoneType' object has no attribute 'rpartition'

On my system this happens with the python module ruamel.yaml. It is in the list sys.modules with name 'ruamel', has a __file__ attribute, but its value is None.
« Last Edit: March 07, 2020, 08:11:10 PM by sciurius » Logged
bvdp
Kara-Moon Master
****
Posts: 1436


WWW
« Reply #1 on: March 07, 2020, 09:10:36 PM »

Neat. I've not done any MMA debugging for several weeks Smiley Oh, and in my defense on this one, I didn't write the code Smiley

But, could you post a short chuck of calling code for this please to save me writing it. I _think_ I see the problem, but I want to do it right.

Thanks so much for the report!
Logged

My online life: http://www.mellowood.ca
sciurius
Sr. Member
****
Posts: 443



« Reply #2 on: March 07, 2020, 09:37:01 PM »

This plugin should do:

https://github.com/sciurius/mma-plugins/tree/master/copyright

Crashing depends on whether you have modules without __file__. You can check with this small program:

Code:
import sys
for module in sys.modules.values():
    if module is None or not hasattr(module, "__file__"):
        continue
    if module.__file__ is None:
        print(module.__name__)

Logged
bvdp
Kara-Moon Master
****
Posts: 1436


WWW
« Reply #3 on: March 08, 2020, 06:18:42 PM »

I have traced it down to a problem with _getCallerModule() and offer this as an ugly replacement.

Code:
def _getCallerModule():
    f = _getCallerFileName()
    if f is None:
        return None
       
    for module in sys.modules.values():
        if module is None or not hasattr(module, "__file__"):
            continue
        try:
            if module.__file__.rpartition(".")[0] != f.rpartition(".")[0]:
                continue
        except:
            continue
        return module
   
    return None
   

And, no I don't think this is the real fix. Wrapping a bit of code with try/except is not good programming. But, for now I want to make sure that the bug is isolated. Please let me know.
Logged

My online life: http://www.mellowood.ca
bvdp
Kara-Moon Master
****
Posts: 1436


WWW
« Reply #4 on: March 08, 2020, 06:35:23 PM »

I meant to add that this bug is only present in Python3. Using Python2 avoids the program Smiley
Logged

My online life: http://www.mellowood.ca
sciurius
Sr. Member
****
Posts: 443



« Reply #5 on: March 08, 2020, 07:28:53 PM »

Modern Fedora has practically banned out python2, and with reason.

Anyway, why not try something simpler like:

    if module is None or not hasattr(module, "__file__") or module.__file__ is None:
Logged
bvdp
Kara-Moon Master
****
Posts: 1436


WWW
« Reply #6 on: March 08, 2020, 09:21:36 PM »

Thanks for the fix. I was going to do something like this later, but you beat me to it. Seems to work fine. So, here it is:

Code:
   
def _getCallerModule():
    f = _getCallerFileName()
    if f is None:
        return None
       
    for module in sys.modules.values():
        if module is None or not hasattr(module, "__file__") or module.__file__ is None:
            continue
        if module.__file__.rpartition(".")[0] != f.rpartition(".")[0]:
            continue
        return module
   
    return None

Guess the next developer version will be sooner than later Smiley

Logged

My online life: http://www.mellowood.ca
sciurius
Sr. Member
****
Posts: 443



« Reply #7 on: March 10, 2020, 08:54:41 AM »

Guess the next developer version will be sooner than later Smiley

I know I'm beating that dead horse again, but a github repo would make things easier...
Logged
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Valid XHTML 1.0! Valid CSS!
Page created in 0.046 seconds with 19 queries.