CEFPython won't initialized when called from an application - python

I have a very very specific problem.
I am trying to figure out a way to embed an HTML brower in my app, in order to show some generated HTML content with included javascript.
I tried to do it with wx.html2, but the javascript part just seems to not work.
So I decided to give a try to CEFPython by taking example of the provided wxPython.py demo.
At first, it worked great in the UI I designed.
BUT, the problem is that this UI is intended to be called from another application, as a sort of "plug-in UI". And when launching my wxPython UI from this application, it crashes as soon as cef is initialized (through:
sys.excepthook = cef.ExceptHook
settings = {
"debug": True,
"log_severity": cef.LOGSEVERITY_INFO,
"log_file": "debug.log",
}
cef.Initialize(settings=settings)
app = CefApp(False)
app.MainLoop()
del app
cef.Shutdown()
I keep getting this error:
Python exception: AttributeError
'module' object has no attribute 'argv'
Traceback (most recent call last):
File "<string>", line 248, in <module>
File "<string>", line 36, in main
File "cefpython_py27.pyx", line 626, in cefpython_py27.Initialize
(cefpython_py27.cpp:99136)
AttributeError: 'module' object has no attribute 'argv'
So in the end I have 2 questions:
is there a way with wx.html2 to show HTML content embedding javascript
if not, do you have a clue of what would cause the launched UI to crash? I guess it's a threading matter but I'm not even sure.
Please excuse my english mistakes by the way, as I'm not native.

It seems that your Python environment doesn't behave in a standard manner, you don't provide details how is your Python code called.
The error in cefpython is thrown on this line:
if "--debug" in sys.argv:
application_settings["debug"] = True
https://github.com/cztomczak/cefpython/blob/bbf3597ba47f72db66cf304ab8eb3ccfc3a7130c/src/cefpython.pyx#L631
You have to find out why your Python didn't define "sys.argv". You can easily fix this with code like this: sys.argv = [] before calling cef.Initialize, however you may still encounter other issues due to your non-standard Python environment.

Related

How to redirect Python Syntax Error into a textbox in MFC or other GUI framwork?

I embed Python into my GUI application, when the script throws syntax errors, I want to redirect the error message into a textbox, so I can know where the error is.
My codes is very simple:
Py_Initialize()
PyRun_SimpleString( "execfile('my.py')" );
Py_Finalize();
If the file contains syntax error, it may looks like:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "my.py", line 3, in <module>
app=everedit.Ap
AttributeError: 'module' object has no attribute 'Ap'
The above messages can be seen in a console window, but now I want to cache these messages in a GUI window.
A GUI window don't have a console. I want to output such messages into a text box.
Please note that I embed Python into C++, I want to cache Python's Syntax Error in C++.
As the documentation for PyRun_SimpleString clearly says:
Returns 0 on success or -1 if an exception was raised. If there was an error, there is no way to get the exception information.
So, if you want to get the exception information, you have to use slightly lower-level functions.
Meanwhile, once you're using the right function, and it returns NULL or -1 to tell you an exception occurred, how do you get the exception information (and distinguish SyntaxError from other exceptions, for whatever reason you want to do that)?
There's a whole chapter in the C-API docs on Exception Handling. But briefly: You call PyErr_Occurred to get the type of the exception. Then you call PyErr_ExceptionMatches to check whether it's the type you want. If so, use PyErr_Fetch to get the value and traceback so you can format them yourself, or PyErr_Format to get a simple formatted string, or whatever else you want. Then you just extract the Unicode or ASCII bytes from the string and put them in your GUI window.
Use a try/catch block and the traceback module (docs).
import traceback
try:
PyParser_SimpleParseString(input())
except SyntaxError as e:
# There will always be one line, but we're better off still looping over the list
# To be extra safe!
for line in traceback.format_exception_only(e.__class__, str(e)):
print(line) # Replace this with what write to the GUI
This will only give you the SyntaxError: x part, if you also want the traceback, use traceback.format_exception.

How to use the navigation-policy-decision-requested signal in Python Webkit

How can I use the navigation-policy-decision-requested (or equivalent) in association with webkit_web_policy_decision_ignore()?
The following is a small outtake form my code (the rest is just a wrapper and settings etc):
def check(view, frame, req, nav, policy):
webkit_web_policy_decision_ignore(TRUE)
...
view.connect("navigation-policy-decision-requested", check)
When I load a new page this error is returned:
Traceback (most recent call last):
File "browser.py", line 17, in check_exec
webkit_web_policy_decision_ignore(TRUE)
NameError: global name 'webkit_web_policy_decision_ignore' is not defined
What I'm trying to achieve is that if a certain address have been given, actions will be taken to prevent it from loading via Python. Any suggestions are welcome in the comments and any additional information you may need will be provided upon request.
Now I'm new to Python so please be specific in your answer, criticism and suggestions.
If you are using pygtk, try policy.ignore().
The object names are mapped slightly differently in pygtk. In python shell you can try after executing from gi.repository import WebKit
print dir(WebKit)
to find corresponding object and in your case
help(WebKit.WebPolicyDecision)

Make _tkinter.createfilehandler work again (or provide a workaround)

I've got some old Python scripts which used a different version of tkinter than the current systems are equipped with. Back in the old days, a method named _tkinter.createfilehandler() existed and worked. With the current versions this returns with a RuntimeError exception:
Traceback (most recent call last):
File "src/text.py", line 513, in <module>
tkinter.createfilehandler(pipe_r, READABLE, drain_pipe)
RuntimeError: _tkinter.createfilehandler not supported for threaded Tcl
The script I'm trying to get to run is this (shortened version of course):
#!/usr/bin/env python
import os
from Tkinter import *
(pipe_r, pipe_w) = os.pipe()
# ...
def drain_pipe(a, b):
# handle data from pipe_r
# ...
tkinter.createfilehandler(pipe_r, READABLE, drain_pipe)
tk.mainloop()
Is there a simple way to get this running again? I'm sure there is a way to convert the scripts (or maybe write them anew based on a different paradigm), but I'd be happy with a hack to not have to change very much (maybe there's a switch to enable this again somehow) because I've got several such scripts and would prefer not to have to patch a lot.
If tk is a Tk() object, then use tk.createfilehandler instead.

pythonw.exe is not responding

I have been learning Python2.7 for a little bit now. I'm using Windows 7 64 bit BTW. I started learning GUI's and have been trying to use wxpython and IDLE for this. So I type out some code:
import wx
app = wx.App()
win = wx.Frame(None)
win.Show()
app.MainLoop()
I run the program, and the window pops up, but the blue doughnut is there. I try to close the window, and it says that pythonw.exe is not responding. Another window pops up about wxpython. It says:
wxPython stdout/stderr(Not Responding)
Traceback (most recent call last):
**IDLE Internal Exception:
File "C:\Python27\lib\idlelib\run.py", line 93, in main
seq, request = rpc.request_queue.get(block=True, timeout=0.05)
File "C:\Python27\lib\Queue.py", line 177, in get
self.not_empty.wait(remaining)
File "C:\Python27\lib\threading.py", line 263, in wait
_sleep(delay)
typeError: 'int' object is not callable
What is wrong and how do I fix it?
Thanks.
The crash is most likely happening at the point when you try and start the event loop. See this bug report: http://bugs.python.org/issue989712
Seems someone else has gone as far to try and create an extension to handle this ability: http://idlex.sourceforge.net/extensions.html
Basically, don't do this from IDLE. Write a script and run it from the shell or the script directly if in windows, by naming it with a .pyw extension and double clicking it. There is apparently a conflict between IDLE's own event loop and the ones from GUI toolkits.
It seems that something might be polluting variables in the threading library, it looks like _sleep variable is being overwritten with an int value; in which case _sleep(x) will not work since _sleep is an int and ints are not callable.
It may be in your client code or in some framework code or libraries you are importing. Is that all of the code?
Try running this code from a plain python terminal, not from an IDE like IDLE.

A simple python program not being able to access my dll

I have created a simple MFC .dll file and I am able to access it via another MFC Application program. I was trying to do the same thing using Python 3.2.2 but after I load my library, It does not detect the function in my dll and gives an error like:
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
File "C:\Python32\lib\ctypes\__init__.py", line 353, in __getattr__
func = self.__getitem__(name)
File "C:\Python32\lib\ctypes\__init__.py", line 358, in __getitem__
func = self._FuncPtr((name_or_ordinal, self))
AttributeError: function 'SayHello' not found
..
I have trying to find a simple program to access my MFC dll file using Python but have got no success as of yet. Just to let everyone know, I have read on ctypes and have been searching lots to get this working. My main aim is to use Python as a scripting language to interface with my MFC C++ dll. I have been reading lots and the closest one I could get to was with PythonWin. Please help in this regard.
Cheers.
I have been able to get a hold of my problem and have solved it. For those who might expect this in the future, I would just like to paste the python script code in order to make your functions accessible in your python scripts. The way to go with your C++ function is obviously to declare this in your .dll file.
extern "C" __declspec(dllexport) int SayHello(int strNo);
and your Python script should go something like this: (getattr() function is required to access your c++ function in your python script)
mydll = cdll.LoadLibrary("Location.dll")
hellofunc = getattr(mydll,'SayHello')
func2.restype = c_int
func2.argtypes = [c_int]
x = func2(34)
print(x)
...
If anyone thinks I might be wrong, please feel free to correct me. I am a beginner in Python, it worked for me this way and I am able to go ahead with my scripting after this.
Hope this helps others.
Cheers.

Categories