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

PyRevitCPythonNotSupported #155

Open
jpdon2503 opened this issue Feb 29, 2024 · 14 comments
Open

PyRevitCPythonNotSupported #155

jpdon2503 opened this issue Feb 29, 2024 · 14 comments

Comments

@jpdon2503
Copy link

I am using revit 2024 and revit python shell 2.0.2, i cant import forms from pyrevit( from pyrevit import forms) i get this error
Exception : System.Exception: PyRevitCPythonNotSupported
at Microsoft.Scripting.Interpreter.ThrowInstruction.Run(InterpretedFrame frame)
at Microsoft.Scripting.Interpreter.Interpreter.HandleException(InterpretedFrame frame, Exception exception)
at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)
at Microsoft.Scripting.Interpreter.LightLambda.Run2[T0,T1,TRet](T0 arg0, T1 arg1)
at IronPython.Runtime.Method.MethodBinding.SelfTarget(CallSite site, CodeContext context, Object target)
at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0 arg0, T1 arg1)
at Microsoft.Scripting.Interpreter.FuncCallInstruction5.Run(InterpretedFrame frame) at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame) at Microsoft.Scripting.Interpreter.LightLambda.Run3[T0,T1,T2,TRet](T0 arg0, T1 arg1, T2 arg2) at IronPython.Compiler.Ast.CallExpression.Invoke0Instruction.Run(InterpretedFrame frame) at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame) at Microsoft.Scripting.Interpreter.LightLambda.Run3[T0,T1,T2,TRet](T0 arg0, T1 arg1, T2 arg2) at System.Dynamic.UpdateDelegates.UpdateAndExecute4[T0,T1,T2,T3,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2, T3 arg3) at IronPython.Runtime.Method.MethodBinding1.SelfTarget(CallSite site, CodeContext context, Object target, T0 arg0)
at IronPython.Compiler.Ast.CallExpression.Invoke1Instruction.Run(InterpretedFrame frame)
at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)
at Microsoft.Scripting.Interpreter.LightLambda.Run3[T0,T1,T2,TRet](T0 arg0, T1 arg1, T2 arg2)
at Microsoft.Scripting.Interpreter.FuncCallInstruction5.Run(InterpretedFrame frame) at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame) 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) 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 Microsoft.Scripting.Interpreter.FuncCallInstruction9.Run(InterpretedFrame frame)
at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)
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)
at _check_name_wrapper$683(Closure , PythonFunction , Object , Object , Object , Object )
at System.Dynamic.UpdateDelegates.UpdateAndExecute4[T0,T1,T2,T3,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2, T3 arg3)
at IronPython.Runtime.Method.MethodBinding1.SelfTarget(CallSite site, CodeContext context, Object target, T0 arg0) at System.Dynamic.UpdateDelegates.UpdateAndExecute3[T0,T1,T2,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2) at Microsoft.Scripting.Interpreter.FuncCallInstruction6.Run(InterpretedFrame frame)
at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)
at Microsoft.Scripting.Interpreter.LightLambda.Run4[T0,T1,T2,T3,TRet](T0 arg0, T1 arg1, T2 arg2, T3 arg3)
at IronPython.Runtime.PythonContext.Call(CodeContext context, Object func, Object arg0)
at IronPython.Runtime.Importer.FindAndLoadModuleFromImporter(CodeContext context, Object importer, String fullName, PythonList path, Object& ret)
at IronPython.Runtime.Importer.TryLoadMetaPathModule(CodeContext context, String fullName, PythonList path, Object& ret)
at IronPython.Runtime.Importer.ImportNestedModule(CodeContext context, PythonModule module, ArraySegment1 parts, PythonList path, String scopeModuleName) at IronPython.Runtime.Importer.ImportFrom(CodeContext context, Object from, String name) at IronPython.Modules.Builtin.__import__(CodeContext context, String name, Object globals, Object locals, Object fromlist, Int32 level) at Microsoft.Scripting.Interpreter.FuncCallInstruction7.Run(InterpretedFrame frame)
at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)
at Microsoft.Scripting.Interpreter.LightLambda.Run8[T0,T1,T2,T3,T4,T5,T6,T7,TRet](T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7)
at IronPython.Runtime.Importer.ImportLightThrow(CodeContext context, String fullName, PythonTuple from, Int32 level)
at Microsoft.Scripting.Interpreter.FuncCallInstruction`5.Run(InterpretedFrame frame)
at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)
at Microsoft.Scripting.Interpreter.LightLambda.Run2[T0,T1,TRet](T0 arg0, T1 arg1)
at IronPython.Compiler.PythonScriptCode.RunWorker(CodeContext ctx)
at Microsoft.Scripting.Hosting.ScriptSource.Execute(ScriptScope scope)
at Microsoft.Scripting.Hosting.ScriptSource.ExecuteAndWrap(ScriptScope scope, ObjectHandle& exception)

@ay-ex
Copy link

ay-ex commented Apr 10, 2024

@jpdon2503 :
Since it might be related to: #46 , may I suggest a different issue title?
Something along those lines: "pyrevit forms are not loading in RPS"

I had the same error message, so I checked in the pyrevit source code at:
C:\ProgramData\pyrevit_4.8.14\pyrevitlib\pyrevit\forms\__init__.py
where the message is thrown:

if PY3 and not IRONPY340:
    raise PyRevitCPythonNotSupported('pyrevit.forms')

Since Ironpython in RPS 2.0.2 is Ironpython3.4.1,
and the pyrevit IRONPY340 check is only looking for specifically 3.4.0 python version, the error is thrown.

After going back to RPS 2.0.1 which has exactly the checked 3.4.0 IronPython version,
that error will not appear anymore. 🙂

...BUT:
Unfortunately for something like:

from pyrevit import forms

user_input = forms.ask_for_string()

you might get this error instead: 🤔

... from pyrevit import forms

>>> user_input = forms.ask_for_string(default="default_", prompt="prompt_", title="title_")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\ProgramData\pyrevit_4.8.14\pyrevitlib\pyrevit\forms\__init__.py", line 3389, in ask_for_string
  File "C:\ProgramData\pyrevit_4.8.14\pyrevitlib\pyrevit\forms\__init__.py", line 705, in show
  File "C:\ProgramData\pyrevit_4.8.14\pyrevitlib\pyrevit\forms\__init__.py", line 667, in __init__
  File "C:\ProgramData\pyrevit_4.8.14\pyrevitlib\pyrevit\forms\__init__.py", line 171, in __init__
  File "C:\ProgramData\pyrevit_4.8.14\pyrevitlib\pyrevit\forms\__init__.py", line 194, in load_xaml
TypeError: LoadComponent() takes exactly 3 arguments (2 given)

Where it seems like wpf.LoadComponent (or more precisely IronPython.Modules.Wpf.LoadComponent )
in version 3.4.0 needs three args (an additional CodeContext) instead of two.
Here the comparison:

  • wpf on rps ironpython 2.7.7:
    image
  • wpf on rps ironpython 3.4.0:
    image

So if someone has suggestions to get the pyrevit.forms working on RPS,
that would be highly appreciated. 🙏

@jmcouffin
Copy link

with latest pyRevit, on the develop-4 branch the issue has been resolved
https://github.com/eirannejad/pyRevit/pull/2188/files#diff-a515bad6f5702c6da744665845255026e089352d268615b295e4af01c42fa314

try changing the ipy engine for something newer than 2.7.7.0

you could use the wip installers of pyrevit to get the fix

@ay-ex ay-ex mentioned this issue Apr 10, 2024
@ay-ex
Copy link

ay-ex commented Apr 10, 2024

@jmcouffin thank for the quick feedback! 🙂
I will try that. (for the above test on rps 2.0.1 both: my pyrevit engine and rps ironpyhton were set to 3.4.0 🤔 )

@jmcouffin
Copy link

this error is a common one and due to the way the ironpython wpf is brought in. Depending on the way, it requires the CodeContext passed as well _ which is unwanted. Proper usgae of LoadComponent should be 2 args only.

@ay-ex
Copy link

ay-ex commented Apr 10, 2024

thank you for the explanation.
this is great news: the wpf issue is one of the main reasons we kept installs of pyrevit in our office at ipy277 version, so we have a reliable matching version of rps (ipy 277).
looking forward to switch to matching set of rps(ipy 3.4) and pyrevit(ipy3.4) 😌

@jmcouffin
Copy link

looking forward to switch to matching set of rps(ipy 3.4) and pyrevit(ipy3.4)

Not sure, it will happen anytime soon, not like this year, I mean.
Not many things are compatible with ipy340 in pyrevit and its library. But I may be wrong

@ay-ex
Copy link

ay-ex commented Apr 10, 2024

I see. thank you for the estimation.
well the pyrevit preview IPY340PR engine was there since a while, but I guess most users still target the tried and true 2.7x 🤔

so far tests on my end look promising - after removing all dependencies to rpw, most of our pyrevit buttons seem ready. 🙂

(
I mean in an ideal world, I would switch to only CPython in pyRevit,
having a wonderfully ergonomic ptpython repl/console/shell invoked directly from pyRevit. ☺️
(and although I was actually recently able to get ptpython to embed into cpython pyrvt,
unfortunately the console there is not a cmd-like terminal environment, so ptpython is not working there properly.)
)

@ay-ex
Copy link

ay-ex commented Apr 10, 2024

@jmcouffin thank you so much!
linking directly to the ipy340 wpf dll path, similar to your linked patch worked!
now I got the pyrevit.forms working for both pyrevit (ipy3.4.0) and rps (3.4.0) : 😀
image

@ay-ex
Copy link

ay-ex commented Apr 10, 2024

ok, I spoke to soon: while does now work reliably on rps, it does not always on pyrevit. 🤔
@jmcouffin do you now what the trigger is, that sometimes it wants the 3 args instead of the 2?
Is it a timing thing, which addon gets to load which dlls first?

@jmcouffin
Copy link

ok, I spoke to soon: while does now work reliably on rps, it does not always on pyrevit. 🤔 @jmcouffin do you now what the trigger is, that sometimes it wants the 3 args instead of the 2? Is it a timing thing, which addon gets to load which dlls first?

Maybe a persistent engine is required?

@ay-ex
Copy link

ay-ex commented Apr 11, 2024

@jmcouffin what would this persistent engine look like?


it seems like I have pyrevit.forms wpf reliably working now on this machine, for both rps (ipy3.4.0) and pyrevit(py3.4.0) :

  • rps: in init.py I use the clr.AddReferenceToFileAndPath and preimport wpf:
import clr
clr.AddReference("IronPython")
import IronPython

wpf_dllpath = r"C:\ProgramData\pyrevit_4.8.14\bin\engines\IPY340PR\pyRevitLabs.IronPython.Wpf.dll"
clr.AddReferenceToFileAndPath(wpf_dllpath)
import wpf
  • pyrevit: I reverted to pyRevit 4.8.14 to before the linked patch above.

BUT:
in pyrevt, as soon as I AddReference as shown above in the screenshot,
again I get the 2/3-args-wpf-loadcomponent-error from above.
but only in pyrevit, not in rps.
with the following snippets I can reproducibly run or break it on my current machine:

  • this works for rps and pyrevit:
import clr


def show_clr_refs_filtered(search_text):
    print("show_clr_refs_filtered:")
    for ref in clr.References:
        if search_text.lower() in ref.ToString().lower():
            print(35*"-")
            print(ref)
            print(ref.Location)
    print(35*"=")


show_clr_refs_filtered("wpf")


from pyrevit import forms


user_input = forms.ask_for_string(default="received_user_input")
print(user_input)

import wpf
print(wpf.LoadComponent.__doc__)

show_clr_refs_filtered("wpf")
  • this does not work on pyrvt but does work on rps:
import clr
wpf_dllpath = r"C:\ProgramData\pyrevit_4.8.14\bin\engines\IPY340PR\pyRevitLabs.IronPython.Wpf.dll"
clr.AddReferenceToFileAndPath(wpf_dllpath)
import wpf
print(wpf.LoadComponent.__doc__)

import clr


def show_clr_refs_filtered(search_text):
    print("show_clr_refs_filtered:")
    for ref in clr.References:
        if search_text.lower() in ref.ToString().lower():
            print(35*"-")
            print(ref)
            print(ref.Location)
    print(35*"=")


show_clr_refs_filtered("wpf")


from pyrevit import forms


user_input = forms.ask_for_string(default="received_user_input")
print(user_input)

show_clr_refs_filtered("wpf")

which is rather puzzling to me, since I assumed the pyrevit wpf dll referenced to in the second snippet,
is exactly the one I am using for the pyrevit.forms. 🤔

equally puzzling I find, that in pyrevit in both cases - the one with the error and the one without -
the call signature for wpf.LoadComponent shows 2 args for all overloads: 🤔

image

but the errors with the message it would need 3 args.

@jmcouffin or maybe @eirannejad : do you know what is going on there?

@ay-ex
Copy link

ay-ex commented Apr 11, 2024

aha, I think now I got at least a lead: 🕵️
``wpf` is a different thing in different places:
it seems to be a module in the pyrevit button script context, but a class inside pyrevit init.py

image

@ay-ex
Copy link

ay-ex commented Apr 11, 2024

ok and if for ipy340 engine
in C:\ProgramData\pyrevit_4.8.14\pyrevitlib\pyrevit\framework.py
wpf is loaded with
clr.AddReferenceToFileAndPath(wpf_dllpath)
instead of
wpf = IronPython.Modules.Wpf
it works 🎉 for pyrvt(ipy340):

image

image

as they are now in both contexts a module. ☺️

so my interpretation is (please correct me if I am wrong):
just PY3 does not help to distinguish python3 from ironpython3, as a not yet existing
PY_IMPL = sys.implementation.name could.

I assume the wpf = IronPython.Modules.Wpf was meant for PY3/PY_IMPL="cpython"
and the clr.AddReferenceToFileAndPath(wpf_dllpath);import wpf should be used for PY3/PY_IMPL="ironpython" ?

@ay-ex
Copy link

ay-ex commented Apr 11, 2024

@jpdon2503 does the following resolve your error message?:

for rps 2.0.1: in init.py import wpf:

import clr
wpf_dllpath = r"C:\ProgramData\pyrevit_4.8.14\bin\engines\IPY340PR\pyRevitLabs.IronPython.Wpf.dll"
clr.AddReferenceToFileAndPath(wpf_dllpath)
import wpf

you would need to replace wpf_dllpath with your pyrevit wpf dll path in the above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants