Possible bug: path value disappearing on hook expression being resolved?

Hi there! I am noticing some very strange behavior. For context, I have created the file pm-config-default2/hooks/tk-multi-loader2/tk-aftereffects_actions.py to try and fix a bug that was spotted, where on exr sequence double click in the loader, “add_to_project” was adding all exr files in the folder instead of the sequence selected. I have also modified the tk-multi-loader2.yml file to source the config path over the original. The engine.py and import_footage.py files still live in the app-store location, and were only modified to log messages.

Here is the custom code I have:

        if name == _ADD_TO_PROJECT:
            file_path = path
            # self.parent.logger("this is the path: {}".format(file_path))
            app.logger.debug("this is the path: {}".format(file_path))
            app.logger.debug("this is the type of the path: {}".format(type(path)))
            if os.path.splitext(path)[-1] == ".exr":
                split_path = file_path.split(".")
                file_path = six.ensure_text("{}.%04d.{}".format(split_path[0], split_path[-1]))
            app.logger.debug("this is the new path: {}".format(file_path))
            app.logger.debug("this is the type of the path: {}".format(type(file_path)))

            self.parent.engine.import_filepath(path)
            app.logger.debug("and now trying the changed path")
            self.parent.engine.import_filepath(file_path)

and here, most interestingly, is the output:

2023-05-15 20:57:51,657 [4464 DEBUG sgtk.env.project.tk-aftereffects.tk-multi-loader2] this is the path: [path_to_frames]\RUN_sh010_light_example_v002_spheres_UTIL.1001.exr
2023-05-15 20:57:51,659 [4464 DEBUG sgtk.env.project.tk-aftereffects.tk-multi-loader2] this is the type of the path: <class 'str'>

2023-05-15 20:57:51,661 [4464 DEBUG sgtk.env.project.tk-aftereffects.tk-multi-loader2] this is the new path: [path_to_frames]\RUN_sh010_light_example_v002_spheres_UTIL.%04d.exr

2023-05-15 20:57:51,673 [4464 DEBUG sgtk.env.project.tk-aftereffects.tk-multi-loader2] this is the type of the path: <class 'str'>

2023-05-15 20:57:51,813 [4464 DEBUG sgtk.env.project.tk-aftereffects] <ProxyWrapper for remote object: type=File, name=RUN_sh010_light_example_v002_spheres_UTIL.1001.exr>

2023-05-15 20:57:51,816 [4464 DEBUG sgtk.env.project.tk-aftereffects] and the path: [path_to_frames]\RUN_sh010_light_example_v002_spheres_UTIL.1001.exr

2023-05-15 20:57:52,221 [4464 DEBUG sgtk.core.platform.bundle] <Sgtk Engine 0x25bee40c988: tk-aftereffects, env: shot_step>: Resolved hook expression (associated with setting 'import_footage_hook'): '{self}/import_footage.py' -> ['[config_location]\\.config\\shotgun\\install\\app_store\\tk-aftereffects\\v0.3.3\\hooks\\import_footage.py']

2023-05-15 20:57:52,606 [4464 WARNING sgtk.env.project.tk-aftereffects.hook.import_footage] here's the path: [path_to_frames]\RUN_sh010_light_example_v002_spheres_UTIL.1001.exr

2023-05-15 20:57:52,979 [4464 WARNING sgtk.env.project.tk-aftereffects.hook.import_footage] this is -, and this is ext: [path_to_frames]\RUN_sh010_light_example_v002_spheres_UTIL.1001 .exr

2023-05-15 20:57:53,235 [4464 WARNING sgtk.env.project.tk-aftereffects.hook.import_footage] default types: {'.mov': 3813, '.avi': 3813}

2023-05-15 20:57:58,188 [4464 DEBUG sgtk.env.project.tk-aftereffects.tk-multi-loader2] and now trying the changed path

2023-05-15 20:57:58,398 [4464 DEBUG sgtk.env.project.tk-aftereffects] <ProxyWrapper for remote object: type=File, name=RUN_sh010_light_example_v002_spheres_UTIL.%04d.exr>

2023-05-15 20:57:58,400 [4464 DEBUG sgtk.env.project.tk-aftereffects] and the path: [path_to_frames]\RUN_sh010_light_example_v002_spheres_UTIL.%04d.exr

2023-05-15 20:57:58,978 [4464 DEBUG sgtk.core.platform.bundle] <Sgtk Engine 0x25bee40c988: tk-aftereffects, env: shot_step>: Resolved hook expression (associated with setting 'import_footage_hook'): '{self}/import_footage.py' -> ['[config_path]\\.config\\shotgun\\install\\app_store\\tk-aftereffects\\v0.3.3\\hooks\\import_footage.py']

2023-05-15 20:57:59,355 [4464 WARNING sgtk.env.project.tk-aftereffects.hook.import_footage] here's the path:

2023-05-15 20:57:59,783 [4464 WARNING sgtk.env.project.tk-aftereffects.hook.import_footage] this is -, and this is ext:

2023-05-15 20:58:00,130 [4464 WARNING sgtk.env.project.tk-aftereffects.hook.import_footage] default types: {'.mov': 3813, '.avi': 3813}

2023-05-15 20:58:02,316 [4464 WARNING sgtk.env.project.tk-aftereffects.hook.import_footage] Filepath '' cannot be imported.

As you can hopefully see from what is printed, the modified filepath data seems to disappear after the hook is resolved (the “and the path” string is coming from engine.py, so I know the data exists at least until that point).

Does anyone have any idea what is going on here? It is clearly able to pass the original string in without problem, but when I try and modify the sequence to be “%04d” (or ####, or @@@@) the path disappears. Is this a bug? Is there something else happening that I don’t understand?

Also, just in case this is important, SG Desktop is running on Windows but my code is being developed in Pycharm on Linux.

Update for in case someone in the future finds this and has a similar issue:

The reason the path “disappears” is because in the engine and import_footage, the path is retrieved from import_options.file.fsName, and the fsName is the filesystem name so it has to be a real path and not a sequence representation.

To fix the bug where it loads all sequences under a parent folder regardless of path, here was my modified code:

        if name == _ADD_TO_PROJECT:
            # special handling for bug where multiple sequences live in same folder
            if os.path.splitext(path)[-1] == ".exr":
                split_path = path.split(".")
                sequence_path = "{}.####.{}".format(split_path[0], split_path[-1])
                first_frame, last_frame = self.parent.engine.find_sequence_range(sequence_path)
                # custom implementation of code
                import_options = self.parent.engine.adobe.ImportOptions()
                path = self.parent.engine.adobe.File(path)
                import_options.file = path
                import_options.sequence = True
                import_options.forceAlphabetical = False
                import_options.rangeStart = first_frame
                import_options.rangeEnd = last_frame
                import_options.importAs = self.parent.engine.adobe.ImportAsType.FOOTAGE
                self.parent.engine.adobe.app.project.importFile(import_options)
            else:
                self.parent.engine.import_filepath(path)

Hopefully this helps someone!