Pathlib usage makes attribute disappear

I have a module with some torch.jit.exported methods and some regular methods. This module has some attributes that I want to use in non-scripted methods. These attributes disappear when I script the module.

class Foo:
    def __init__(self):
        # Commenting out this line gets rid of the AttributeError
        pathlib.Path("/tmp/tmp").mkdir(parents=True, exist_ok=True)
        self.y = 5

class M(nn.Module):
    def __init__(self, f):
        super(M, self).__init__()
        self.f = f

    @torch.jit.ignore
    def get_f(self):
        return self.f  # <-- Getting an attribute error here

m = torch.jit.script(M(Foo()))
m.get_f()

I am curious if this is a bug or there is some rationale behind this. It seems like assigning self.f = f in M.__init__ makes torch script analyze Foo.__init__ and discard the attribute if scripting it fails.

Because I never use this attribute in compiled methods, there should not be a reason to try compiling it and discarding. Maybe there is some annotation I can use to ask torch script to just keep this attribute attached to M? Is there some “good” workaround?

I’m not sure I understand the use case completely, but you are indeed using it in the scripted m module.
If you create an eager module first, the attribute will be there:

module = M(Foo())
m = torch.jit.script(module)
m.get_f() # error
module.get_f() # works

Yeah, the attribute is obviously there before scripting. My questions are:

  • Why scripting removes this attribute when it is used only in torch.jit.ignore'ed methods?
  • Is there a good way to make torch.jit.script not remove this attribute? I can just do m.f = f to assign it again after scripting, but this is fairly ugly when you have many attributes.

I’m not sure, if there is a way to ignore attributes, which seems to be your case. I.e. if you initialize Foo as an nn.Module it would also be scripted as a RecursiveScriptModule, but I guess you don’t want that.