Skip to content

Faulty modules handling #261

@pierreglaser

Description

@pierreglaser

in #136, a test testing bad interactions happening in pickle.whichmodule was enhanced. But actually, it mangles 2 different use-cases into one:

The first use-case is calling pickle.whichmodule on an object with __module__ set to None. In this case, whichmodule loops through all imported modules, trying to find the object in each of them using the object's name.

This loop can error out if a potentially unrelated module throws an exceptions when someone tries to call getattr on it. Here is a reconstructed minimal example

import pickle
import sys


class UnrelatedTroublesomeModuleClass:
    def __getattr__(self, name):
        raise Exception

unrelated_troublesome_module = UnrelatedTroublesomeModuleClass()

# nothings prevents us from adding this instance to sys.modules
sys.modules['unrelated_troublesome_module'] = unrelated_troublesome_module

class A:
    def f(self):
        pass
    f.__module__ = None

# fails when looping over sys.modules and calling
# `` getattr(unrelated_troublesome_module, 'A')``
a = pickle.whichmodule(A, 'A')

The second use-case is when the object actually points to a faulty module, via its __module__ attribute. This module can for instance throw a Exception when calling gettattr on it. In this situation, exceptions can happen on pickle.whichmodule AND, further along the way during getattr(module, name) calls in save_function. Change the line f.__module__ = None to f.__module__ = 'unrelated_troublesome_module' to switch between the first and the second use-case.

2 remarks:

  • I think we want to support the use-case 1, meaning that we do not want unrelated faulty modules to cause failures when trying to infer the module of a given object
  • However, if this object explicitally points to a faulty module, I think we should not try/except the subsequent errors, but rather do not interfere. If the module throws an error when trying to call getattr, let it happen.

We may also want to implement our own whichmodule, that silently discards errors happening when calling getattr.

@ogrisel

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions