I am having an intermittent error causing my Python module to crash, and I'm assuming it's because of a memory error occurring by not getting the refcounts correct in the c code. I have a bit of code that gets a response at a random time from a remote location. Based on the data received, it needs to update a data variable which I should have access to in Python. What's the best way to accomplish this? The following code runs most of the time, and it works correctly when it does, but when it doesn't it crashes Python (bringing up the visual studio debug box). Thanks.
if (event == kResponseEvent) {
list = PyList_New(0);
for (i = 0; i < event->count; i++) {
PyList_Append(list, Py_BuildValue("{s:i, s:s}",
"id", event->id,
"name", event->name));
}
PyModule_AddObject(module, "names", list);
}
PyModule_AddObject() steals a reference. As such, you should not be decrefing list after.
PyList_New() can return NULL to indicate an error, which you aren't checking for. Py_BuildValue() can return NULL to indicate an error, which you aren't checking for. PyList_Append() can return -1 to indicate an error, which you're also not checking for. PyList_Append() doesn't steal the reference, so you're leaking the reference to the dict returned by Py_BuildValue(). The latter may be causing you to run out of memory, which can cause Py_BuildValue() or PyList_Append() to fail, and your failure to handle the error can cause a crash.
(Something else can also cause Py_BuildValue() or PyList_Append() to fail, but that's hard to guess at from just this snippet.)
Related
I want to use the Delphi 4 Python components from here https://github.com/pyscripter/python4delphi
but I don't want to drop the components on a form, I want everything in code , my code goes like this :
var
PythonEngine_netA: TPythonEngine;
PythonInputOutput_netA: TPythonInputOutput;
begin
PythonEngine_netA := TPythonEngine.Create(Self);
PythonInputOutput_netA := TPythonInputOutput.Create(Self);
try
/// configure the components
PythonEngine_netA.DllName:='python39.dll';
PythonEngine_netA.IO := PythonInputOutput_netA;
PythonEngine_netA.UseLastKnownVersion := True;
PythonInputOutput_netA.OnSendUniData := PythonInputOutput_SendUniData;
PythonInputOutput_netA.UnicodeIO := True;
PythonInputOutput_netA.RawOutput := True;
/// execute the script
PythonEngine_netA.ExecString(UTF8Encode(mmo_pythoncode.text));
finally
PythonEngine_netA.free;
PythonInputOutput_netA.free;
end;
execution of this code fails, error msg : "Python is not properly initialized",
what did I miss to use this code ?
One quick look at PythonEngine.pas (or even better: always search all files for the error message to find out where and why an error is returned) tells me you missed calling PythonEngine_netA.Initialize().
Also note that /Demos describes:
Demo34 Dynamically creating, destroying and recreating PythonEngine. Uses PythonVersions
So please have a look at /Demos/Demo34/Unit1.pas how it is done there with (almost) no components. Or run the whole project in general, preferably in debug mode single stepping thru it be aware which method does what.
You just forgot to load the Dll:
PythonEngine_netA.UseLastKnownVersion:= True;
//PythonEngine_netA.opendll(PYDLL)
PythonEngine_netA.LoadDll;
PythonEngine_netA.IO:= PythonInputOutput_netA;
I'm working with IronPython in a C#/.Net Core 3.1 project and I need to be able to validate a script before executing it in a production environment.
I have found this solution, creating my custom Microsoft.Scripting.Hosting.ErrorListener implementation:
public class IronPythonListener : ErrorListener
{
public List<ValidationError> Errors = new List<ValidationError>();
public override void ErrorReported(ScriptSource source, string message, SourceSpan span, int errorCode, Severity severity)
{
Errors.Add(new ValidationError
{
Message = message,
ErrorCode = errorCode,
Severity = severity,
Span = span
});
}
}
and then passing an instance of it to the Microsoft.Scripting.Hosting.ScriptSource.Compile(ErrorListener) method:
IronPythonListener listener = new IronPythonListener();
ScriptEngine engine = Python.CreateEngine();
ScriptSource scriptSource = engine.CreateScriptSourceFromString(script, SourceCodeKind.AutoDetect);
CompiledCode code = scriptSource.Compile(listener);
In listener.Errors list I find all the compilation errors.
This solution works, but for my purposes it is not complete, because for example:
if the passed script is something like my_var = 5 + "some text", listener.Errors is empty and the script is considered valid even though it cannot be executed (in fact, it throws a unsupported operand type(s) for +: 'int' and 'str' exception)
if the passed script contains calls to undefined functions (e.g. length(my_string) instead of len(my_string)), it is considered valid
Another thing that seems strange to me is that all the errors I can find are of type Severity.FatalError (e.g. passing my_var = 6 +), but I'm not able to find any Severity.Error or Severity.Warning.
Is there a way to improve the validation, without executing my compiled script?
Thanks in advance for any help, unfortunately I cannot find so much documentation about this.
Edit: I found some online validators (e.g. https://repl.it/languages/python3 or http://pep8online.com/) and they also don't provide a complete python validation (in the former one, validation is handled better by the IDE, but the 5 + "some text" error is detected only at execution time). Of course I can try to execute the script and catch the exception when listener.Errors is empty, but it would be better to avoid this.
Edit 2: I tried also this solution, using a separated python script to validate mine, but I have the same issues with undefined functions and wrong operators usage.
In python, you can learn memory location of variables by using id function, so:
X = "Hello world!"
print(id(X)) # Output is equal to 139806692112112 (0x7F27483876F0)
I'm tried to access to variable with pointers in C (Surely the other program still alive):
#include <stdio.h>
int main(void){
char *x = (char *) 0x7F27483876F0;
printf("%s\n", x);
return 0;
}
I compile the code, no errors or warnings but when i tried the running program OS giving a Segmentation error. How i can solve this problem?
Or is it possible?
Doing something like this is more and more impossible these days. With features like address space layout randomization you can't really tell where a given program, let alone variable will load in actual memory.
Best bet is to use some type of message passing. Not sure why all the downvotes on your question, but it seems like a reasonably put question, even if not technically feasible these days.
I've written a python program which read a stdout of another process by the pipe redirection.
However, the program sucks in this line:
print "[Input Thread] ", self.inputPipe.readline(ii)
The error is IOError: [Errno 0] Error
I found the explanation of windows errno 0. It makes confused because it defined as:
The operation completed successfully.
Why does an operation completed successfully lead to an error?
The name can trick you but ERROR_SUCCESS actually means there was no error.
From https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382.aspx:
ERROR_SUCCESS
0 (0x0)
The operation completed successfully.
I know this is kind of old but having spent a fair amount of time trying to find a complete answer without success. So I figured I'd share what I've figured out.
The complete answer of how this happens, is when the pInvoke method you called "fails" but not because of an error.
huh you think
For example lets say you need to unhook a windows hook, but it gets called twice due to a bit of spaghetti or a paranoid level of defensive programming in your object architecture.
// hook assigned earlier
// now we call our clean up code
if (NativeMethods.UnhookWindowsHookEx(HookHandle) == 0)
{
// method succeeds normally so we do not get here
Log.ReportWin32Error("Error removing hook", Marshal.GetLastWin32Error());
}
// other code runs, but the hook is never reattached,
// due to paranoid defensive program you call your clean up code twice
if (NativeMethods.UnhookWindowsHookEx(HookHandle) == 0)
{
// pInvoke method failed (return zero) because there was no hook to remove
// however there was no error, the hook was already gone thus ERROR_SUCCESS (0)
// is our last error
Log.ReportWin32Error("Error removing hook", Marshal.GetLastWin32Error());
}
The windows API can be tricky. Most likely, the error number was not properly retrieved by the second program you mentioned. It was either overwritten or not pulled in at all; so it defaulted to 0.
You didn't say what the other program was; but for example, in .net, it is easy to omit the 'SetLastError' flag when declaring your external calls.
[DllImport('kernel32.dll', SetLastError = true)]
https://www.medo64.com/2013/03/error-the-operation-completed-successfully/
I am developing automated test cases for my app using selenium RC in python 2.7. When I am using wait_for_time_to_load(time) is throwing error as the timeout is variable in my app. Can anyone suggest me any other alternative for the function "wait_for_page_to_load" which does not take time as a parameter.
Thanks
Just to add to #rs79's code
int iteration = 0;
//checks the presence of element till a given no of iterations(say 20) to avoid infinite loop
while(!(selenium.isElementPresent("yourelement")) && iteration < 20){
Thread.sleep(1000);
iteration++;
}
again this is in java, hopefully you can apply same logic in python.
You could check for the absence of an expected element and keep waiting till it appears.
while (!(selenium.isElementPresent("your_element_identifier")==true)) {
selenium.setSpeed("10");
Thread.sleep(10);
}
Evidently, the code above is in Java, but applying the same login in Python should be trivial.