Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: app-init hook not working as intended (pyRevit 5) #2351

Closed
5 tasks done
aussieBIMguru opened this issue Aug 16, 2024 · 14 comments
Closed
5 tasks done

[Bug]: app-init hook not working as intended (pyRevit 5) #2351

aussieBIMguru opened this issue Aug 16, 2024 · 14 comments
Assignees
Labels
Bug Bug that stops user from using the tool or a major portion of pyRevit functionality [class] pyRevit 5 pyRevit 5 coming release
Milestone

Comments

@aussieBIMguru
Copy link

✈ Pre-Flight checks

  • I don't have SentinelOne antivirus installed (see above for the solution)
  • I have searched in the issues (open and closed) but couldn't find a similar issue
  • I have searched in the pyRevit Forum for similar issues
  • I already followed the installation troubleshooting guide thoroughly
  • I am using the latest pyRevit Version

🐞 Describe the bug

The app-init based hook appears to not work in pyRevit 5 WIP. Letting the team know so they can look into it when time allows.

⌨ Error/Debug Message

IronPython Traceback:
Traceback (most recent call last):
 File "C:\Users\gavin.crump\OneDrive - Architectus\Documents\GitHub\pyRarch\Toolbar\Panel.extension\hooks\app-init.py", line 2, in <module>
 File "C:\Program Files\pyRevit-Master\pyrevitlib\pyrevit\__init__.py", line 60, in <module>
AttributeError: 'Application' object has no attribute 'Application'

Script Executor Traceback:
System.MissingMemberException: 'Application' object has no attribute 'Application'
 at IronPython.Runtime.Binding.PythonGetMemberBinder.FastErrorGet`1.GetError(CallSite site, TSelfType target, CodeContext context) in D:\a\pyRevit\pyRevit\dev\modules\pyRevitLabs.IronPython2\Src\IronPython\Runtime\Binding\PythonGetMemberBinder.cs:line 180
 at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0 arg0, T1 arg1)
 at Microsoft.Scripting.Interpreter.FuncCallInstruction`5.Run(InterpretedFrame frame) in /_/Src/Microsoft.Dynamic/Interpreter/Instructions/CallInstruction.Generated.cs:line 750
 at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame) in /_/Src/Microsoft.Dynamic/Interpreter/Interpreter.cs:line 91
 at Microsoft.Scripting.Interpreter.LightLambda.Run2[T0,T1,TRet](T0 arg0, T1 arg1) in /_/Src/Microsoft.Dynamic/Interpreter/LightLambda.Generated.cs:line 86
 at IronPython.Compiler.PythonScriptCode.RunWorker(CodeContext ctx) in D:\a\pyRevit\pyRevit\dev\modules\pyRevitLabs.IronPython2\Src\IronPython\Compiler\PythonScriptCode.cs:line 65
 at IronPython.Compiler.RuntimeScriptCode.InvokeTarget(Scope scope) in D:\a\pyRevit\pyRevit\dev\modules\pyRevitLabs.IronPython2\Src\IronPython\Compiler\RuntimeScriptCode.cs:line 85
 at IronPython.Runtime.PythonContext.InitializeModule(String fileName, ModuleContext moduleContext, ScriptCode scriptCode, ModuleOptions options) in D:\a\pyRevit\pyRevit\dev\modules\pyRevitLabs.IronPython2\Src\IronPython\Runtime\PythonContext.cs:line 1129
 at IronPython.Runtime.Importer.LoadModuleFromSource(CodeContext context, String name, String path) in D:\a\pyRevit\pyRevit\dev\modules\pyRevitLabs.IronPython2\Src\IronPython\Runtime\Importer.cs:line 925
 at IronPython.Runtime.Importer.LoadFromDisk(CodeContext context, String name, String fullName, String str) in D:\a\pyRevit\pyRevit\dev\modules\pyRevitLabs.IronPython2\Src\IronPython\Runtime\Importer.cs:line 875
 at IronPython.Runtime.Importer.ImportFromPathHook(CodeContext context, String name, String fullName, List path, Func`5 defaultLoader) in D:\a\pyRevit\pyRevit\dev\modules\pyRevitLabs.IronPython2\Src\IronPython\Runtime\Importer.cs:line 842
 at IronPython.Runtime.Importer.ImportFromPath(CodeContext context, String name, String fullName, List path) in D:\a\pyRevit\pyRevit\dev\modules\pyRevitLabs.IronPython2\Src\IronPython\Runtime\Importer.cs:line 816
 at IronPython.Runtime.Importer.ImportTopAbsolute(CodeContext context, String name) in D:\a\pyRevit\pyRevit\dev\modules\pyRevitLabs.IronPython2\Src\IronPython\Runtime\Importer.cs:line 609
 at IronPython.Runtime.Importer.ImportModule(CodeContext context, Object globals, String modName, Boolean bottom, Int32 level) in D:\a\pyRevit\pyRevit\dev\modules\pyRevitLabs.IronPython2\Src\IronPython\Runtime\Importer.cs:line 243
 at IronPython.Modules.Builtin.__import__(CodeContext context, String name, Object globals, Object locals, Object fromlist, Int32 level) in D:\a\pyRevit\pyRevit\dev\modules\pyRevitLabs.IronPython2\Src\IronPython\Modules\Builtin.cs:line 73
 at Microsoft.Scripting.Interpreter.FuncCallInstruction`7.Run(InterpretedFrame frame) in /_/Src/Microsoft.Dynamic/Interpreter/Instructions/CallInstruction.Generated.cs:line 798
 at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame) in /_/Src/Microsoft.Dynamic/Interpreter/Interpreter.cs:line 91
 at Microsoft.Scripting.Interpreter.LightLambda.Run7[T0,T1,T2,T3,T4,T5,T6,TRet](T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) in /_/Src/Microsoft.Dynamic/Interpreter/LightLambda.Generated.cs:line 271
 at System.Dynamic.UpdateDelegates.UpdateAndExecute6[T0,T1,T2,T3,T4,T5,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5)
 at IronPython.Runtime.Importer.ImportLightThrow(CodeContext context, String fullName, PythonTuple from, Int32 level) in D:\a\pyRevit\pyRevit\dev\modules\pyRevitLabs.IronPython2\Src\IronPython\Runtime\Importer.cs:line 53
 at Microsoft.Scripting.Interpreter.FuncCallInstruction`5.Run(InterpretedFrame frame) in /_/Src/Microsoft.Dynamic/Interpreter/Instructions/CallInstruction.Generated.cs:line 750
 at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame) in /_/Src/Microsoft.Dynamic/Interpreter/Interpreter.cs:line 91
 at Microsoft.Scripting.Interpreter.LightLambda.Run2[T0,T1,TRet](T0 arg0, T1 arg1) in /_/Src/Microsoft.Dynamic/Interpreter/LightLambda.Generated.cs:line 86
 at IronPython.Compiler.PythonScriptCode.RunWorker(CodeContext ctx) in D:\a\pyRevit\pyRevit\dev\modules\pyRevitLabs.IronPython2\Src\IronPython\Compiler\PythonScriptCode.cs:line 65
 at IronPython.Compiler.RuntimeScriptCode.InvokeTarget(Scope scope) in D:\a\pyRevit\pyRevit\dev\modules\pyRevitLabs.IronPython2\Src\IronPython\Compiler\RuntimeScriptCode.cs:line 85
 at Microsoft.Scripting.Hosting.CompiledCode.Execute(ScriptScope scope) in /_/Src/Microsoft.Scripting/Hosting/CompiledCode.cs:line 63
 at PyRevitLabs.PyRevit.Runtime.IronPythonEngine.Execute(ScriptRuntime& runtime)

♻️ To Reproduce

Make a hook for app-init.py
When opening Revit app in 2025, message will show

⏲️ Expected behavior

app-init script runs as per lower builds

🖥️ Hardware and Software Setup (please complete the following information)

C:\Users\gavin.crump>pyrevit env
==> Registered Clones (full git repos)
==> Registered Clones (deployed from archive/image)
master | Deploy: "basepublic" | Branch: "master" | Version: "5.0.0.24227+1428-wip" | Path: "C:\Program Files\pyRevit-Master"
==> Attachments
master | Product: "Autodesk Revit 2025" | Engine: DEFAULT (2712) | Path: "C:\Program Files\pyRevit-Master" | AllUsers
master | Product: "24.2.1" | Engine: DEFAULT (2712) | Path: "C:\Program Files\pyRevit-Master" | AllUsers
master | Product: "23.1.5" | Engine: DEFAULT (2712) | Path: "C:\Program Files\pyRevit-Master" | AllUsers
master | Product: "2022.1.5" | Engine: DEFAULT (2712) | Path: "C:\Program Files\pyRevit-Master" | AllUsers
master | Product: "2021.1.10" | Engine: DEFAULT (2712) | Path: "C:\Program Files\pyRevit-Master" | AllUsers
master | Product: "2020.2.9" | Engine: DEFAULT (2712) | Path: "C:\Program Files\pyRevit-Master" | AllUsers
==> Installed Extensions
Panel | Type: Unknown | Repo: "" | Installed: "C:\Users\gavin.crump\OneDrive - Architectus\Documents\GitHub\pyRarch\Toolbar\Panel.extension"
==> Default Extension Search Path
C:\Users\gavin.crump\AppData\Roaming\pyRevit\Extensions
==> Extension Search Paths
C:\Users\gavin.crump\OneDrive - Architectus\Documents\GitHub\pyRarch\Toolbar
==> Extension Sources - Default
https://github.com/pyrevitlabs/pyRevit/raw/master/extensions/extensions.json
==> Extension Sources - Additional
==> Installed Revits
Autodesk Revit 2025 | Version: 25.0.2.419 | Build: 20240307_1300(x64) | Language: 1033 | Path: "C:\Program Files\Autodesk\Revit 2025\"
24.2.1 | Version: 24.2.10.64 | Build: 20240408_1515(x64) | Language: 1033 | Path: "C:\Program Files\Autodesk\Revit 2024\"
23.1.5 | Version: 23.1.50.23 | Build: 20240709_1030(x64) | Language: 1033 | Path: "C:\Program Files\Autodesk\Revit 2023\"
2022.1.5 | Version: 22.1.50.17 | Build: 20230915_1530(x64) | Language: 1033 | Path: "C:\Program Files\Autodesk\Revit 2022\"
2021.1.10 | Version: 21.1.100.12 | Build: 20240319_1700(x64) | Language: 1033 | Path: "C:\Program Files\Autodesk\Revit 2021\"
2020.2.9 | Version: 20.2.90.12 | Build: 20220517_1515(x64) | Language: 1033 | Path: "C:\Program Files\Autodesk\Revit 2020\"
==> Running Revit Instances
PID: 17008 | Autodesk Revit 2025 | Version: 25.0.2.419 | Build: 20240307_1300(x64) | Language: 0 | Path: "C:\Program Files\Autodesk\Revit 2025"
==> User Environment
Microsoft Windows 10 [Version 10.0.22631]
Executing User: ARCHITECTUS\gavin.crump
Active User: ARCHITECTUS\gavin.crump
Admin Access: No
%APPDATA%: "C:\Users\gavin.crump\AppData\Roaming"
Latest Installed .Net Framework: 8.0.0
Installed .Net Target Packs: v4.0 v4.5 v4.5.1 v4.5.2 v4.6 v4.6.1 v4.7.2 v4.8 v4.X
Installed .Net-Core Target Packs: v6.0.401
pyRevit CLI v5.0.0.24227+1428-wip.807907d3acc8f7b165dfff1e8c766581185ee86b

Additional context

I appreciate pyRevit 5 is WIP, just sharing for team to investigate when time suits - pyRevit still loads afterwards so it's not a major issue for now.

@aussieBIMguru aussieBIMguru added the Bug Bug that stops user from using the tool or a major portion of pyRevit functionality [class] label Aug 16, 2024
@aussieBIMguru
Copy link
Author

aussieBIMguru commented Aug 16, 2024

Just adding that this appears to be for any event handle that isn't command Id based. I've got it for doc-synced and doc-syncing also. If I manually address the line causing the error (version check), it proceeds on to have issues on line 83 regarding the engine attribute not being found.

@sanzoghenzo
Copy link
Contributor

sanzoghenzo commented Aug 16, 2024

Thanks @aussieBIMguru for reporting this.

We have introduced this bug by accessing the __revit__ variable thinking it is always an UIApplication object, while in fact it can also be an Application or a UIControlledApplication based on the event sender. As the message tells us, in this case we already have an Application that's why it errors.

For a quick fix, we need to check the type of __revit__ and act accordingly;
A wiser choice would be to rethink this behavior and always set it to the UIApplication, and using other variables to hold the Application instance.

@aussieBIMguru
Copy link
Author

aussieBIMguru commented Aug 16, 2024

No worries, if something other than __revit__ holds the application instance in future it would be good to know what that new thing becomes, as I use the __revit__.application syntax to check for the active version of Revit in my custom tools (this still seems to work). Appreciate your taking the time to let me know the cause and potential pathways that could be taken to resolve in future.

You've all done a brilliant job so far with pyRevit5, very few things have broken in my toolbar (aside from losing my Excel reader, but thats a netcore thing vs pyRevit, and my toast forms which I found a new option for), so great job!

@jmcouffin jmcouffin added the pyRevit 5 pyRevit 5 coming release label Aug 16, 2024
@sanzoghenzo
Copy link
Contributor

sanzoghenzo commented Aug 18, 2024

@aussieBIMguru @jmcouffin could you please try to replace those lines

# try get net folder
net_folder = "netfx"
if int(__revit__.Application.VersionNumber) >= 2025:
net_folder = "netcore"

with the following and see if it solves the issue?

def _get_revit_version():
    if __revit__ is None:
        raise Exception('Critical Error. __revit__ handle is not available.')
    try:
        # UIApplication
        return __revit__.Application.VersionNumber
    except AttributeError:
        try:
            # Application, (ControlledApplication)
            return __revit__.VersionNumber
        except AttributeError:
            # UIControlledApplication
            return __revit__.ControlledApplication.VersionNumber


# try get net folder
net_folder = "netcore" if int(_get_revit_version()) >= 2025 else "netfx"

@sanzoghenzo
Copy link
Contributor

As a note, I believe that the first lines of pyrevit\__init__.py (until PYREVIT_CLI_PATH) should be moved to C#, since pyrevit is a library/package that shouldn't mess with sys.path (even more so that it adds its own path to sys.path, but it already should have happened since it was imported by some other code...)

@aussieBIMguru
Copy link
Author

@aussieBIMguru @jmcouffin could you please try to replace those lines

# try get net folder
net_folder = "netfx"
if int(__revit__.Application.VersionNumber) >= 2025:
net_folder = "netcore"

with the following and see if it solves the issue?

def _get_revit_version():
    if __revit__ is None:
        raise Exception('Critical Error. __revit__ handle is not available.')
    try:
        # UIApplication
        return __revit__.Application.VersionNumber
    except AttributeError:
        try:
            # Application, (ControlledApplication)
            return __revit__.VersionNumber
        except AttributeError:
            # UIControlledApplication
            return __revit__.ControlledApplication.VersionNumber


# try get net folder
net_folder = "netcore" if _get_revit_version() >= 2025 else "netfx"

Thanks @sanzoghenzo, although that appears to have caused downstream issues in the code I think (pyrevit doesn't load afterwards). I've disabled my hooks for now, but if any other ideas you wish to test in the code do let me know.

image

@sanzoghenzo
Copy link
Contributor

I forgot an int at the last line, so it always picked the .net framework folder, even for revit 2025.
I updated my previous post, see if it works now.

@aussieBIMguru
Copy link
Author

aussieBIMguru commented Aug 19, 2024

Great! That looks to have fixed the issue and allowed the hooks to work as intended in 2025.

I also had to account for the same issue in pyRevit\runtime\__init__.py as well as in framework.py which feature the same __revit__.application code.

I've tested the fix in versions 2021-2025, and ran a few tools to ensure it hasn't broadly jumbled the core functionality of pyRevit itself. I can see using an IDE that the version number is also being used in the 'Copy views' tool as well as the Assembly maker module ('asmmaker.py').

Hope that helps lay down the pathway to the broader fix in the code. Thanks @sanzoghenzo.

@jmcouffin
Copy link
Contributor

@sanzoghenzo Let me know if you take care of this or I need to do it.
Thanks @aussieBIMguru

@sanzoghenzo
Copy link
Contributor

I'm at work handling a big emergency, so if you want a quick fix go ahead an do it 😉

@aussieBIMguru
Copy link
Author

No rush from my side on this, I've told my company we'll wait for the stable build before we roll anything out.

Hope everything is OK @sanzoghenzo!

@jmcouffin
Copy link
Contributor

draft PR #2363

@sanzoghenzo
Copy link
Contributor

sanzoghenzo commented Aug 21, 2024

@eirannejad can you explain why __revit__ could be so many different things? Most of the scripts expect it to be an UIApplication.

Also, could we break things in pyrevit5, totally get rid of the __revit__ builtin and force everybody to use HOST_APP.uiapp/app?

@jmcouffin jmcouffin added this to the pyRevit 5 RC milestone Aug 22, 2024
@jmcouffin
Copy link
Contributor

fixed by #2363

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Bug that stops user from using the tool or a major portion of pyRevit functionality [class] pyRevit 5 pyRevit 5 coming release
Projects
Status: Done
Development

No branches or pull requests

3 participants