About Python (not the snake)

Linux specific forum
ccode
User
User
Posts: 99
Joined: Sat Jun 23, 2018 5:21 pm

About Python (not the snake)

Post by ccode »

Hello!

How to continue a Python script after reading values?

Jump to "; -Problem":
Why is the next "Python_RunString" crashing?

Thanks for any help.

Example:

Code: Select all

;Easy-Python

EnableExplicit

DeclareModule EasyPython
  Macro Python_INCREF(op)
    op\ob_refcnt + 1
  EndMacro
  
  Macro Python_XINCREF(op)
    If op : Python_INCREF(op) : EndIf
  EndMacro
  
  Macro Python_DECREF(op)
    op\ob_refcnt - 1
  EndMacro
  
  Macro Python_XDECREF(op)
    If op : Python_DECREF(op) : EndIf
  EndMacro
  
  Declare.i Python_Init()
  Declare.b Python_Close()
  Declare.s Python_GetVersion()
  Declare.b Python_RunString(PythonString.s)
  Declare.s Python_GetFunction(PythonFunction.s, PythonParameter.s = "", PythonModule.s = "__main__")
  Declare.b Python_CallScript(FileID, PythonScript.s)
  Declare.s Python_GetItem(PythonValue.s, PythonModule.s = "__main__")
  Declare.b Python_SetItem(PythonValue.s, Insert.s, PythonModule.s = "__main__")
EndDeclareModule

Module EasyPython
  EnableExplicit
  
  CompilerSelect #PB_Compiler_OS
    CompilerCase #PB_OS_Windows
      Global Python_Libname$ = "python36.dll"
      Macro OSPrototype
        PrototypeC
      EndMacro
    CompilerCase #PB_OS_Linux
      Global Python_Libname$ = "libpython3.6m.so.1.0"
      Macro OSPrototype
        PrototypeC
      EndMacro
    CompilerCase #PB_OS_MacOS
      Global Python_Libname$ = "python.so"
      Macro OSPrototype
        PrototypeC
      EndMacro
  CompilerEndSelect
  
  Global PythonLib.i
  
  
  Structure _typeobject Align #PB_Structure_AlignC
    *ob_base
    *tp_name            ; For printing, in format "<module>.<name>"
    tp_basicsize.i
    tp_itemsize.i       ; For allocation
    
    ; Methods To implement standard operations
    
    *tp_dealloc
    *tp_print
    *tp_getattr
    *tp_setattr
    *tp_reserved     ; formerly known as tp_compare
    *tp_repr
    
    ; Method suites For standard classes
    
    *tp_as_number
    *tp_as_sequence
    *tp_as_mapping
    
    ; More standard operations (here For binary compatibility)
    
    *tp_hash
    *tp_call
    *tp_str
    *tp_getattro
    *tp_setattro
    
    ; Functions To access object As input/output buffer
    *tp_as_buffer
    
    ; Flags To Define presence of optional/expanded features
    tp_flags.i
    
    *tp_doc      ; Documentation string
    
    ; Assigned meaning in release 2.0
    ; call function For all accessible objects
    *tp_traverse
    
    ; delete references To contained objects
    *tp_clear
    
    ; Assigned meaning in release 2.1
    ; rich comparisons
    *tp_richcompare
    
    ; weak reference enabler
    tp_weaklistoffset.i
    
    ; Iterators
    *tp_iter
    *tp_iternext
    
    ; Attribute descriptor And subclassing stuff
    *tp_methods
    *tp_members
    *tp_getset
    *tp_base
    *tp_dict
    *tp_descr_get
    *tp_descr_set
    *tp_dictoffset
    *tp_init
    *tp_alloc
    *tp_new
    *tp_free      ; Low-level free-memory routine
    *tp_is_gc     ; For PyObject_IS_GC
    *tp_bases
    *tp_mro      ; method resolution order
    *tp_cache
    *tp_subclasses
    *tp_weaklist
    *tp_del
    
    ; Type attribute cache version tag. Added in version 2.6
    tp_version_tag.u
    
    CompilerIf 1 = 0  ;COUNT_ALLOCS
                      ; these must be last And never explicitly initialized
      tp_allocs.i
      tp_frees.i
      tp_maxalloc.i
      *tp_prev
      *tp_next
    CompilerEndIf
  EndStructure
  
  Structure PythonObject Align #PB_Structure_AlignC
    *_ob_next
    *_ob_prev
    ob_refcnt.i
    *ob_type._typeobject
  EndStructure
  
  OSPrototype.i Py_GetProgramFullPath()
  OSPrototype.i Py_GetVersion()
  OSPrototype.i Py_GetPlatform()
  OSPrototype.i Py_GetCopyright()
  OSPrototype.i Py_GetCompiler()
  OSPrototype.i Py_GetBuildInfo()
  OSPrototype Py_SetPythonHome(*String.p-UTF8)
  OSPrototype.i Py_GetPythonHome()
  OSPrototype Py_SetPath(*String.p-unicode)
  OSPrototype.i Py_GetPath()
  OSPrototype Py_SetProgramName(*String.p-UTF8)
  OSPrototype.i Py_GetProgramName()
  OSPrototype Py_Initialize()
  OSPrototype Py_InitializeEx(initsigs.l)
  OSPrototype Py_Finalize()
  OSPrototype Py_IncRef(*PyObject)
  OSPrototype Py_DecRef(*PyObject)
  OSPrototype.i PyCallable_Check(*PyObject)
  OSPrototype.i PyDict_GetItemString(*PyObject, String.p-UTF8)
  OSPrototype.i PyDict_SetItemString(*PyObject1, String.p-UTF8, *PyObject2)
  OSPrototype PyErr_Print()
  OSPrototype.i PyErr_Occurred()
  OSPrototype PyErr_Clear()
  OSPrototype.i PyImport_AddModule(String.p-UTF8)
  OSPrototype.i PyLong_AsLong(*PyObject)
  OSPrototype.i PyLong_FromLong(Value.l)
  OSPrototype.d PyFloat_AsDouble(*PyObject)
  OSPrototype.i PyString_FromString(String.p-UTF8)
  OSPrototype.i PyObject_Repr(exc_type)
  OSPrototype.i PyString_AsString(*PyObject)
  OSPrototype.i PyString_AsStringAndSize(*PyObject, *buffer, length.i)
  OSPrototype.i PyModule_GetDict(*PyObject)
  OSPrototype.i PyObject_GetAttrString(*PyObject, String.p-UTF8)
  OSPrototype.i PyObject_CallObject(*PyObject1, *PyObject2)
  OSPrototype.i PyRun_SimpleString(String.p-UTF8)
  OSPrototype.i PyTuple_New(Len.i)
  OSPrototype.i PyTuple_SetItem(*PyObject1, Size.i, *PyObject2)
  OSPrototype.i PyUnicode_FromString(String.p-UTF8)
  OSPrototype.i PyUnicode_FromObject(*PyObject)
  OSPrototype.i PyUnicode_AsUnicode(*PyObject)
  OSPrototype.i PyUnicode_AsUTF8(*PyObject)
  OSPrototype.i PyArg_Parse(*args, format.p-UTF8, *char)
  
  Procedure.i Python_Init()
    PythonLib = OpenLibrary(#PB_Any, Python_Libname$)
    If PythonLib
      Global Pyth_GetProgramFullPath.Py_GetProgramFullPath = GetFunction(PythonLib, "Py_GetProgramFullPath")   
      Global Pyth_GetVersion.Py_GetVersion = GetFunction(PythonLib, "Py_GetVersion")
      Global Pyth_GetPlatform.Py_GetPlatform = GetFunction(PythonLib, "Py_GetPlatform")
      Global Pyth_GetCopyright.Py_GetCopyright = GetFunction(PythonLib, "Py_GetCopyright")
      Global Pyth_GetCompiler.Py_GetCompiler = GetFunction(PythonLib, "Py_GetCompiler")
      Global Pyth_GetBuildInfo.Py_GetBuildInfo = GetFunction(PythonLib, "Py_GetBuildInfo")
      Global Python_SetPythonHome.Py_SetPythonHome = GetFunction(PythonLib, "Py_SetPythonHome")
      Global Pyth_GetPythonHome.Py_GetPythonHome = GetFunction(PythonLib, "Py_GetPythonHome")
      Global Python_SetPath.Py_SetPath = GetFunction(PythonLib, "Py_SetPath")
      Global Pyth_GetPath.Py_GetPath = GetFunction(PythonLib, "Py_GetPath")
      Global Python_SetProgramName.Py_SetProgramName = GetFunction(PythonLib, "Py_SetProgramName")
      Global Pyth_GetProgramName.Py_GetProgramName = GetFunction(PythonLib, "Py_GetProgramName")
      Global Python_Initialize.Py_Initialize = GetFunction(PythonLib, "Py_Initialize")
      Global Python_InitializeEx.Py_InitializeEx = GetFunction(PythonLib, "Py_InitializeEx")
      Global Python_Finalize.Py_Finalize = GetFunction(PythonLib, "Py_Finalize")
      Global Python_IncRef.Py_IncRef = GetFunction(PythonLib, "Py_IncRef")
      Global Python_DecRef.Py_DecRef = GetFunction(PythonLib, "Py_DecRef")
      Global PythonCallable_Check.PyCallable_Check = GetFunction(PythonLib, "PyCallable_Check")
      Global PythonDict_GetItemString.PyDict_GetItemString = GetFunction(PythonLib, "PyDict_GetItemString")
      Global PythonDict_SetItemString.PyDict_SetItemString = GetFunction(PythonLib, "PyDict_SetItemString")
      Global PythonErr_Print.PyErr_Print = GetFunction(PythonLib, "PyErr_Print")
      Global PythonErr_Occurred.PyErr_Occurred = GetFunction(PythonLib, "PyErr_Occurred")
      Global PythonErr_Clear.PyErr_Clear = GetFunction(PythonLib, "PyErr_Clear")
      Global PythonImport_AddModule.PyImport_AddModule = GetFunction(PythonLib, "PyImport_AddModule")
      Global PythonLong_AsLong.PyLong_AsLong = GetFunction(PythonLib, "PyLong_AsLong")
      Global PythonLong_FromLong.PyLong_FromLong = GetFunction(PythonLib, "PyLong_FromLong")
      Global PythonFloat_AsDouble.PyFloat_AsDouble = GetFunction(PythonLib, "PyFloat_AsDouble")
      Global PythonString_FromString.PyString_FromString = GetFunction(PythonLib, "PyString_FromString")
      Global PythonObject_Repr.PyObject_Repr = GetFunction(PythonLib, "PyObject_Repr")
      Global PythonString_AsString.PyString_AsString = GetFunction(PythonLib, "PyString_AsString")
      Global PythonString_AsStringAndSize.PyString_AsStringAndSize = GetFunction(PythonLib, "PyString_AsStringAndSize")
      Global PythonModule_GetDict.PyModule_GetDict = GetFunction(PythonLib, "PyModule_GetDict")
      Global PythonObject_GetAttrString.PyObject_GetAttrString = GetFunction(PythonLib, "PyObject_GetAttrString")
      Global PythonObject_CallObject.PyObject_CallObject = GetFunction(PythonLib, "PyObject_CallObject")
      Global PythonRun_SimpleString.PyRun_SimpleString = GetFunction(PythonLib, "PyRun_SimpleString")
      Global PythonTuple_New.PyTuple_New = GetFunction(PythonLib, "PyTuple_New")
      Global PythonTuple_SetItem.PyTuple_SetItem = GetFunction(PythonLib, "PyTuple_SetItem")
      Global PythonUnicode_FromString.PyUnicode_FromString = GetFunction(PythonLib, "PyUnicode_InternFromString")
      Global PythonUnicode_FromObject.PyUnicode_FromObject = GetFunction(PythonLib, "PyUnicode_FromObject")
      Global PythonUnicode_AsUnicode.PyUnicode_AsUnicode = GetFunction(PythonLib, "PyUnicode_AsUnicode")
      Global PythonUnicode_AsUTF8.PyUnicode_AsUTF8 = GetFunction(PythonLib, "PyUnicode_AsUTF8")
      Global PythonArg_Parse.PyArg_Parse = GetFunction(PythonLib, "PyArg_Parse")
      Python_Initialize()
    EndIf
    ProcedureReturn PythonLib
  EndProcedure
  
  Procedure.s Python_GetProgramFullPath()
    ProcedureReturn PeekS(Pyth_GetProgramFullPath(), -1, #PB_UTF8)
  EndProcedure
  
  Procedure.s Python_GetVersion()
    ProcedureReturn PeekS(Pyth_GetVersion(), -1, #PB_UTF8)
  EndProcedure
  
  Procedure.s Python_GetPlatform()
    ProcedureReturn PeekS(Pyth_GetPlatform(), -1, #PB_UTF8)
  EndProcedure
  
  Procedure.s Python_GetCopyright()
    ProcedureReturn PeekS(Pyth_GetCopyright(), -1, #PB_UTF8)
  EndProcedure
  
  Procedure.s Python_GetCompiler()
    ProcedureReturn PeekS(Pyth_GetCompiler(), -1, #PB_UTF8)
  EndProcedure
  
  Procedure.s Python_GetBuildInfo()
    ProcedureReturn PeekS(Pyth_GetBuildInfo(), -1, #PB_UTF8)
  EndProcedure
  
  Procedure.s Python_GetPythonHome()
    Protected Result.s, *String
    *String = Pyth_GetPythonHome()
    If *String
      Result = PeekS(*String, -1, #PB_UTF8)
    EndIf
    ProcedureReturn Result
  EndProcedure
  
  Procedure.s Python_GetPath()
    Protected Result.s, *String
    *String = Pyth_GetPath()
    If *String
      Result = PeekS(*String, -1, #PB_UTF8)
    EndIf
    ProcedureReturn Result
  EndProcedure
  
  Procedure.s Python_GetProgramName()
    Protected Result.s, *String
    *String = Pyth_GetProgramName()
    If *String
      Result = PeekS(*String, -1, #PB_UTF8)
    EndIf
    ProcedureReturn Result
  EndProcedure
  
  
  Procedure.b Python_Close()
    If IsLibrary(PythonLib)
      Python_Finalize()
      CloseLibrary(PythonLib)
      PythonLib = #Null
      ProcedureReturn #True
    Else
      ProcedureReturn #False
    EndIf
  EndProcedure
  
  Procedure.b Python_RunString(PythonString.s)
    If PythonRun_SimpleString(PythonString)
      ProcedureReturn #True
    Else
      ProcedureReturn #False
    EndIf
  EndProcedure
  
  Procedure.b Python_CallScript(FileID, PythonScript.s)
    Protected script.s
    If ReadFile(FileID, PythonScript)
      Repeat
        script + ReadString(FileID)+#CRLF$
      Until Eof(FileID)
      CloseFile(FileID)
      PythonRun_SimpleString(script)
      ProcedureReturn #True
    Else
      ProcedureReturn #False
    EndIf
  EndProcedure
  
  Procedure.s Python_GetFunction(PythonFunction.s, PythonParameter.s = "", PythonModule.s = "__main__")
    Protected CountParameters = CountString(PythonParameter, "|"), i.i, Parameter.s
    Protected *pModule.PythonObject, *pFunc.PythonObject, *pArgs.PythonObject, *pValue.PythonObject
    Protected RetValue.s = "", *rstring
    *pModule = PythonImport_AddModule(PythonModule)
    If *pModule
      *pFunc = PythonObject_GetAttrString(*pModule, PythonFunction)
      ; pFunc is a new reference
      If *pFunc And PythonCallable_Check(*pFunc)
        *pArgs = PythonTuple_New((CountParameters+1))
        For i = 0 To CountParameters
          Parameter = StringField(PythonParameter, i + 1, "|")
          *pValue = PythonUnicode_FromString(Parameter)
          If Not *pValue
            Python_DECREF(*pArgs)
            ;Python_DECREF(*pModule)
            RetValue = "Error !! Cannot convert argument"
          EndIf
          ; pValue reference stolen here:
          PythonTuple_SetItem(*pArgs, i, *pValue)
        Next i
        If CountParameters > 0 Or Len(PythonParameter) > 0
          *pValue = PythonObject_CallObject(*pFunc, *pArgs)
        Else
          *pValue = PythonObject_CallObject(*pFunc, #Null)
        EndIf
        If *pValue = #Null
          ProcedureReturn "Error !! "+ PythonFunction +":"
        EndIf
        Python_DECREF(*pArgs)
        If *pValue <> #Null
          *rstring = PythonUnicode_AsUTF8(*pValue)
          If *rstring = #Null
            RetValue = "Error !! The function must return a string."
          Else
            RetValue = PeekS(*rstring,-1,#PB_UTF8)
            Python_DECREF(*pValue)
          EndIf
        Else
          Python_DECREF(*pFunc)
          ;Python_DECREF(*pModule)
          PythonErr_Print()
          RetValue = "Error !! Call failed"
        EndIf
      Else
        If PythonErr_Occurred()
          PythonErr_Print()
          RetValue = "Cannot find function " + PythonFunction
        EndIf
      EndIf
    Else
      PythonErr_Print()
      RetValue = "Error !! Failed to load " + PythonModule
    EndIf
    ProcedureReturn RetValue
  EndProcedure
  
  Procedure.s Python_GetItem(PythonValue.s, PythonModule.s = "__main__")
    Protected *pModule.PythonObject, *pValue.PythonObject
    Protected *rstring, RetValue.s
    *pModule = PythonImport_AddModule(PythonModule)
    If *pModule
      *pValue = PythonObject_GetAttrString(*pModule, PythonValue)
      If *pValue <> #Null
        *rstring = PythonUnicode_AsUTF8(*pValue)
        If *rstring <> #Null
          RetValue = PeekS(*rstring,-1,#PB_UTF8)
        Else
          RetValue = StrD(PythonFloat_AsDouble(*pValue))         
        EndIf
        Python_DECREF(*pValue)
        ProcedureReturn RetValue
      Else
        ProcedureReturn "Error !! Object can not be read: " + PythonValue + " from " + PythonModule
      EndIf
    Else
      ProcedureReturn "Error !! Object can not be read: " + PythonValue + " from " + PythonModule
    EndIf
  EndProcedure
  
  Procedure.b Python_SetItem(PythonValue.s, Insert.s, PythonModule.s = "__main__")
    Protected *pModule.PythonObject, *pDict.PythonObject, *pValue.PythonObject
    *pModule = PythonImport_AddModule(PythonModule)
    If *pModule
      *pDict = PythonModule_GetDict(*pModule)
      *pValue = PythonUnicode_FromString(Insert)
      If *pValue <> #Null
        PythonDict_SetItemString(*pDict, PythonValue, *pValue)
      EndIf
      Python_DECREF(*pValue)
      ProcedureReturn #True
    Else
      ProcedureReturn #False
    EndIf
  EndProcedure
  
EndModule

;-Main
Global pystring.s = "", Answer.s = ""
OpenConsole()
;pystring = "global v"+#CRLF$
pystring = "v = '?'"+#CRLF$ 
pystring + "def test(p1):"+#CRLF$
pystring + " print('Hello from Python.')"+#CRLF$
pystring + " global v"+#CRLF$
pystring + " v = 10+4"+#CRLF$
pystring + " return str(34)"+#CRLF$
;pystring + "v = test(14)"+#CRLF$

EasyPython::Python_Init()
PrintN(EasyPython::Python_GetVersion())
EasyPython::Python_RunString(pystring)
Answer = EasyPython::Python_GetFunction("test", "Hellloooo")
PrintN(Answer)
EasyPython::Python_RunString("print('Hellllloooo!!!!')")

PrintN(EasyPython::Python_GetItem("v"))
EasyPython::Python_SetItem("v", "100")
PrintN(EasyPython::Python_GetItem("v"))

;-Problem

;EasyPython::Python_RunString("v = v + 50") ;Crash during execution. Why?
;PrintN(EasyPython::Python_GetItem("v"))


; EasyPython::Python_CallScript(0, GetCurrentDirectory()+"test.py")
; Answer = EasyPython::Python_GetFunction("emit_pdf", "1")
; PrintN(Answer)
EasyPython::Python_Close()
Input()
CloseConsole()
ccode
User
User
Posts: 99
Joined: Sat Jun 23, 2018 5:21 pm

Re: About Python (not the snake)

Post by ccode »

This is how it works better. (But I have to expand it.)

(The (All) "Python Object"(Structure) contains errors.)

Code: Select all

;Easy-Python

;    _________         _________
;   /         \       /         \ 
;  /  /~~~~~\  \     /  /~~~~~\  \
;  |  |     |  |     |  |     |  |
;  |  |     |  |     |  |     |  |
;  |  |     |  |     |  |     |  |         /
;  |  |     |  |     |  |     |  |       //
; (o  o)    \  \_____/  /     \  \_____/ /
;  \__/      \         /       \        /
;   |         ~~~~~~~~~         ~~~~~~~~
;   ^

EnableExplicit

DeclareModule EasyPython
  ;   Macro Python_INCREF(op)
  ;     op\ob_refcnt + 1
  ;   EndMacro
  ;   
  ;   Macro Python_XINCREF(op)
  ;     If op : Python_INCREF(op) : EndIf
  ;   EndMacro
  ;   
  ;   Macro Python_DECREF(op)
  ;     op\ob_refcnt - 1
  ;   EndMacro
  ;   
  ;   Macro Python_XDECREF(op)
  ;     If op : Python_DECREF(op) : EndIf
  ;   EndMacro
  ;   
  Declare.i Python_Init()
  Declare.b Python_Close()
  Declare.s Python_GetVersion()
  Declare.b Python_RunString(PythonString.s)
  Declare.s Python_GetFunction(PythonFunction.s, PythonParameter.s = "", PythonModule.s = "__main__")
  Declare.b Python_CallScript(FileID, PythonScript.s)
  Declare.s Python_GetItem(PythonValue.s, PythonModule.s = "__main__")
  Declare.b Python_SetItem(PythonValue.s, Insert.s, PythonModule.s = "__main__")
EndDeclareModule

Module EasyPython
  EnableExplicit
  
  CompilerSelect #PB_Compiler_OS
    CompilerCase #PB_OS_Windows
      Global Python_Libname$ = "python36.dll"
      Macro OSPrototype
        PrototypeC
      EndMacro
    CompilerCase #PB_OS_Linux
      Global Python_Libname$ = "libpython3.6m.so.1.0"
      Macro OSPrototype
        PrototypeC
      EndMacro
    CompilerCase #PB_OS_MacOS
      Global Python_Libname$ = "python.so"
      Macro OSPrototype
        PrototypeC
      EndMacro
  CompilerEndSelect
  
  Global PythonLib.i
  
  ;_typeobject object contains bugs
  ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  ;-TODO
  Structure _typeobject Align #PB_Structure_AlignC
    *ob_base
    *tp_name            ; For printing, in format "<module>.<name>"
    tp_basicsize.i
    tp_itemsize.i       ; For allocation
    
    ; Methods To implement standard operations
    
    *tp_dealloc
    *tp_print
    *tp_getattr
    *tp_setattr
    *tp_reserved     ; formerly known as tp_compare
    *tp_repr
    
    ; Method suites For standard classes
    
    *tp_as_number
    *tp_as_sequence
    *tp_as_mapping
    
    ; More standard operations (here For binary compatibility)
    
    *tp_hash
    *tp_call
    *tp_str
    *tp_getattro
    *tp_setattro
    
    ; Functions To access object As input/output buffer
    *tp_as_buffer
    
    ; Flags To Define presence of optional/expanded features
    tp_flags.i
    
    *tp_doc      ; Documentation string
    
    ; Assigned meaning in release 2.0
    ; call function For all accessible objects
    *tp_traverse
    
    ; delete references To contained objects
    *tp_clear
    
    ; Assigned meaning in release 2.1
    ; rich comparisons
    *tp_richcompare
    
    ; weak reference enabler
    tp_weaklistoffset.i
    
    ; Iterators
    *tp_iter
    *tp_iternext
    
    ; Attribute descriptor And subclassing stuff
    *tp_methods
    *tp_members
    *tp_getset
    *tp_base
    *tp_dict
    *tp_descr_get
    *tp_descr_set
    *tp_dictoffset
    *tp_init
    *tp_alloc
    *tp_new
    *tp_free      ; Low-level free-memory routine
    *tp_is_gc     ; For PyObject_IS_GC
    *tp_bases
    *tp_mro      ; method resolution order
    *tp_cache
    *tp_subclasses
    *tp_weaklist
    *tp_del
    
    ; Type attribute cache version tag. Added in version 2.6
    tp_version_tag.u
    
    CompilerIf 1 = 0  ;COUNT_ALLOCS
                      ; these must be last And never explicitly initialized
      tp_allocs.i
      tp_frees.i
      tp_maxalloc.i
      *tp_prev
      *tp_next
    CompilerEndIf
  EndStructure
  
  Structure PythonObject Align #PB_Structure_AlignC
    *_ob_next
    *_ob_prev
    ob_refcnt.i
    *ob_type._typeobject
  EndStructure
  
  OSPrototype.i Py_GetProgramFullPath()
  OSPrototype.i Py_GetVersion()
  OSPrototype.i Py_GetPlatform()
  OSPrototype.i Py_GetCopyright()
  OSPrototype.i Py_GetCompiler()
  OSPrototype.i Py_GetBuildInfo()
  OSPrototype Py_SetPythonHome(*String.p-UTF8)
  OSPrototype.i Py_GetPythonHome()
  OSPrototype Py_SetPath(*String.p-unicode)
  OSPrototype.i Py_GetPath()
  OSPrototype Py_SetProgramName(*String.p-UTF8)
  OSPrototype.i Py_GetProgramName()
  OSPrototype Py_Initialize()
  OSPrototype Py_InitializeEx(initsigs.l)
  OSPrototype Py_Finalize()
  OSPrototype Py_IncRef(*PyObject)
  OSPrototype Py_DecRef(*PyObject)
  OSPrototype.i PyCallable_Check(*PyObject)
  OSPrototype.i PyDict_GetItemString(*PyObject, String.p-UTF8)
  OSPrototype.i PyDict_SetItemString(*PyObject1, String.p-UTF8, *PyObject2)
  OSPrototype.i PyDict_SetItem(*PyObject1, *PyObject2, *PyObject3)
  OSPrototype PyErr_Print()
  OSPrototype.i PyErr_Occurred()
  OSPrototype PyErr_Clear()
  OSPrototype.i PyImport_AddModule(String.p-UTF8)
  OSPrototype.i PyLong_AsLong(*PyObject)
  OSPrototype.i PyLong_FromLong(Value.l)
  OSPrototype.d PyFloat_AsDouble(*PyObject)
  OSPrototype.i PyString_FromString(String.p-UTF8)
  OSPrototype.i PyObject_Repr(exc_type)
  OSPrototype.i PyObject_Str(*PyObject)
  OSPrototype.i PyString_Check(*PyObject)
  OSPrototype.i PyString_AsString(*PyObject)
  OSPrototype.i PyString_AsStringAndSize(*PyObject, *buffer, length.i)
  OSPrototype.i PyModule_GetDict(*PyObject)
  OSPrototype.i PyObject_GetAttrString(*PyObject, String.p-UTF8)
  OSPrototype.i PyObject_SetAttrString(*PyObject1, String.p-UTF8, *PyObject2)
  OSPrototype.i PyObject_CallObject(*PyObject1, *PyObject2)
  OSPrototype.i PyRun_SimpleString(String.p-UTF8)
  OSPrototype.i PyTuple_New(Len.i)
  OSPrototype.i PyTuple_SetItem(*PyObject1, Size.i, *PyObject2)
  OSPrototype.i PyUnicode_FromString(String.p-UTF8)
  OSPrototype.i PyUnicode_FromObject(*PyObject)
  OSPrototype.i PyUnicode_AsUnicode(*PyObject)
  OSPrototype.i PyUnicode_AsUTF8(*PyObject)
  OSPrototype.i PyArg_Parse(*args, format.p-UTF8, *char)
  
  Procedure.i Python_Init()
    PythonLib = OpenLibrary(#PB_Any, Python_Libname$)
    If PythonLib
      Global Pyth_GetProgramFullPath.Py_GetProgramFullPath = GetFunction(PythonLib, "Py_GetProgramFullPath")   
      Global Pyth_GetVersion.Py_GetVersion = GetFunction(PythonLib, "Py_GetVersion")
      Global Pyth_GetPlatform.Py_GetPlatform = GetFunction(PythonLib, "Py_GetPlatform")
      Global Pyth_GetCopyright.Py_GetCopyright = GetFunction(PythonLib, "Py_GetCopyright")
      Global Pyth_GetCompiler.Py_GetCompiler = GetFunction(PythonLib, "Py_GetCompiler")
      Global Pyth_GetBuildInfo.Py_GetBuildInfo = GetFunction(PythonLib, "Py_GetBuildInfo")
      Global Python_SetPythonHome.Py_SetPythonHome = GetFunction(PythonLib, "Py_SetPythonHome")
      Global Pyth_GetPythonHome.Py_GetPythonHome = GetFunction(PythonLib, "Py_GetPythonHome")
      Global Python_SetPath.Py_SetPath = GetFunction(PythonLib, "Py_SetPath")
      Global Pyth_GetPath.Py_GetPath = GetFunction(PythonLib, "Py_GetPath")
      Global Python_SetProgramName.Py_SetProgramName = GetFunction(PythonLib, "Py_SetProgramName")
      Global Pyth_GetProgramName.Py_GetProgramName = GetFunction(PythonLib, "Py_GetProgramName")
      Global Python_Initialize.Py_Initialize = GetFunction(PythonLib, "Py_Initialize")
      Global Python_InitializeEx.Py_InitializeEx = GetFunction(PythonLib, "Py_InitializeEx")
      Global Python_Finalize.Py_Finalize = GetFunction(PythonLib, "Py_Finalize")
      Global Python_IncRef.Py_IncRef = GetFunction(PythonLib, "Py_IncRef")
      Global Python_DecRef.Py_DecRef = GetFunction(PythonLib, "Py_DecRef")
      Global PythonCallable_Check.PyCallable_Check = GetFunction(PythonLib, "PyCallable_Check")
      Global PythonDict_GetItemString.PyDict_GetItemString = GetFunction(PythonLib, "PyDict_GetItemString")
      Global PythonDict_SetItemString.PyDict_SetItemString = GetFunction(PythonLib, "PyDict_SetItemString")
      Global PythonDict_SetItem.PyDict_SetItem = GetFunction(PythonLib, "PyDict_SetItem")
      Global PythonErr_Print.PyErr_Print = GetFunction(PythonLib, "PyErr_Print")
      Global PythonErr_Occurred.PyErr_Occurred = GetFunction(PythonLib, "PyErr_Occurred")
      Global PythonErr_Clear.PyErr_Clear = GetFunction(PythonLib, "PyErr_Clear")
      Global PythonImport_AddModule.PyImport_AddModule = GetFunction(PythonLib, "PyImport_AddModule")
      Global PythonLong_AsLong.PyLong_AsLong = GetFunction(PythonLib, "PyLong_AsLong")
      Global PythonLong_FromLong.PyLong_FromLong = GetFunction(PythonLib, "PyLong_FromLong")
      Global PythonFloat_AsDouble.PyFloat_AsDouble = GetFunction(PythonLib, "PyFloat_AsDouble")
      Global PythonString_FromString.PyString_FromString = GetFunction(PythonLib, "PyString_FromString")
      Global PythonObject_Repr.PyObject_Repr = GetFunction(PythonLib, "PyObject_Repr")
      Global PythonObject_Str.PyObject_Str = GetFunction(PythonLib, "PyObject_Str")
      Global PythonString_Check.PyString_Check = GetFunction(PythonLib, "PyString_Check")
      Global PythonString_AsString.PyString_AsString = GetFunction(PythonLib, "PyString_AsString")
      Global PythonString_AsStringAndSize.PyString_AsStringAndSize = GetFunction(PythonLib, "PyString_AsStringAndSize")
      Global PythonModule_GetDict.PyModule_GetDict = GetFunction(PythonLib, "PyModule_GetDict")
      Global PythonObject_GetAttrString.PyObject_GetAttrString = GetFunction(PythonLib, "PyObject_GetAttrString")
      Global PythonObject_SetAttrString.PyObject_SetAttrString = GetFunction(PythonLib, "PyObject_SetAttrString")
      Global PythonObject_CallObject.PyObject_CallObject = GetFunction(PythonLib, "PyObject_CallObject")
      Global PythonRun_SimpleString.PyRun_SimpleString = GetFunction(PythonLib, "PyRun_SimpleString")
      Global PythonTuple_New.PyTuple_New = GetFunction(PythonLib, "PyTuple_New")
      Global PythonTuple_SetItem.PyTuple_SetItem = GetFunction(PythonLib, "PyTuple_SetItem")
      Global PythonUnicode_FromString.PyUnicode_FromString = GetFunction(PythonLib, "PyUnicode_InternFromString")
      Global PythonUnicode_FromObject.PyUnicode_FromObject = GetFunction(PythonLib, "PyUnicode_FromObject")
      Global PythonUnicode_AsUnicode.PyUnicode_AsUnicode = GetFunction(PythonLib, "PyUnicode_AsUnicode")
      Global PythonUnicode_AsUTF8.PyUnicode_AsUTF8 = GetFunction(PythonLib, "PyUnicode_AsUTF8")
      Global PythonArg_Parse.PyArg_Parse = GetFunction(PythonLib, "PyArg_Parse")
      Python_Initialize()
    EndIf
    ProcedureReturn PythonLib
  EndProcedure
  
  Procedure.s Python_GetProgramFullPath()
    ProcedureReturn PeekS(Pyth_GetProgramFullPath(), -1, #PB_UTF8)
  EndProcedure
  
  Procedure.s Python_GetVersion()
    ProcedureReturn PeekS(Pyth_GetVersion(), -1, #PB_UTF8)
  EndProcedure
  
  Procedure.s Python_GetPlatform()
    ProcedureReturn PeekS(Pyth_GetPlatform(), -1, #PB_UTF8)
  EndProcedure
  
  Procedure.s Python_GetCopyright()
    ProcedureReturn PeekS(Pyth_GetCopyright(), -1, #PB_UTF8)
  EndProcedure
  
  Procedure.s Python_GetCompiler()
    ProcedureReturn PeekS(Pyth_GetCompiler(), -1, #PB_UTF8)
  EndProcedure
  
  Procedure.s Python_GetBuildInfo()
    ProcedureReturn PeekS(Pyth_GetBuildInfo(), -1, #PB_UTF8)
  EndProcedure
  
  Procedure.s Python_GetPythonHome()
    Protected Result.s, *String
    *String = Pyth_GetPythonHome()
    If *String
      Result = PeekS(*String, -1, #PB_UTF8)
    EndIf
    ProcedureReturn Result
  EndProcedure
  
  Procedure.s Python_GetPath()
    Protected Result.s, *String
    *String = Pyth_GetPath()
    If *String
      Result = PeekS(*String, -1, #PB_UTF8)
    EndIf
    ProcedureReturn Result
  EndProcedure
  
  Procedure.s Python_GetProgramName()
    Protected Result.s, *String
    *String = Pyth_GetProgramName()
    If *String
      Result = PeekS(*String, -1, #PB_UTF8)
    EndIf
    ProcedureReturn Result
  EndProcedure
  
  Procedure.b Python_Close()
    If IsLibrary(PythonLib)
      Python_Finalize()
      CloseLibrary(PythonLib)
      PythonLib = #Null
      ProcedureReturn #True
    Else
      ProcedureReturn #False
    EndIf
  EndProcedure
  
  Procedure.b Python_RunString(PythonString.s)
    If PythonRun_SimpleString(PythonString)
      ProcedureReturn #True
    Else
      ProcedureReturn #False
    EndIf
  EndProcedure
  
  Procedure.b Python_CallScript(FileID, PythonScript.s)
    Protected script.s
    If ReadFile(FileID, PythonScript)
      Repeat
        script + ReadString(FileID)+#CRLF$
      Until Eof(FileID)
      CloseFile(FileID)
      PythonRun_SimpleString(script)
      ;PythonErr_Clear()
      ProcedureReturn #True
    Else
      ProcedureReturn #False
    EndIf
  EndProcedure
  
  Procedure.s Python_GetFunction(PythonFunction.s, PythonParameter.s = "", PythonModule.s = "__main__")
    Protected CountParameters = CountString(PythonParameter, "|"), i.i, Parameter.s
    Protected *pModule.PythonObject, *pFunc.PythonObject, *pArgs.PythonObject, *pValue.PythonObject
    Protected RetValue.s = "", *rstring, *pValue_new.PythonObject
    *pModule = PythonImport_AddModule(PythonModule)
    If *pModule
      *pFunc = PythonObject_GetAttrString(*pModule, PythonFunction)
      ; pFunc is a new reference
      If *pFunc And PythonCallable_Check(*pFunc)
        *pArgs = PythonTuple_New((CountParameters+1))
        For i = 0 To CountParameters
          Parameter = StringField(PythonParameter, i + 1, "|")
          *pValue = PythonUnicode_FromString(Parameter)
          If Not *pValue
            RetValue = "Error !! Cannot convert argument"
          EndIf
          ; pValue reference stolen here:
          PythonTuple_SetItem(*pArgs, i, *pValue)
        Next i
        If CountParameters > 0 Or Len(PythonParameter) > 0
          *pValue  = PythonObject_CallObject(*pFunc, *pArgs)
        Else
          *pValue  = PythonObject_CallObject(*pFunc, #Null)
        EndIf
        If *pValue <> #Null
          *pValue_new = PythonObject_Str(*pValue)
          *rstring = PythonUnicode_AsUTF8(*pValue_new)
          RetValue = PeekS(*rstring,-1,#PB_UTF8)
        Else
          PythonErr_Print()
          RetValue = "Error !! Call failed"
        EndIf
      Else
        If PythonErr_Occurred()
          PythonErr_Print()
          RetValue = "Cannot find function " + PythonFunction
        EndIf
      EndIf
    Else
      PythonErr_Print()
      RetValue = "Error !! Failed to load " + PythonModule
    EndIf
    ProcedureReturn RetValue
  EndProcedure
  
  Procedure.s Python_GetItem(PythonValue.s, PythonModule.s = "__main__")
    Protected *pModule.PythonObject, *pValue.PythonObject
    Protected *rstring, RetValue.s, *pValue_new.PythonObject
    *pModule = PythonImport_AddModule(PythonModule)
    If *pModule
      *pValue = PythonObject_GetAttrString(*pModule, PythonValue)
      If *pValue <> #Null
        *rstring = PythonUnicode_AsUTF8(*pValue)
        If *rstring <> #Null
          RetValue = PeekS(*rstring,-1,#PB_UTF8)
        Else
          *pValue_new = PythonObject_Str(*pValue)
          *rstring = PythonUnicode_AsUTF8(*pValue_new)
          RetValue = PeekS(*rstring,-1,#PB_UTF8)
          PythonErr_Clear()
          If *pValue_new = #Null Or *rstring = #Null
            RetValue = "Error !! The Object must return a string."
          EndIf
        EndIf
        ProcedureReturn RetValue
      Else
        ProcedureReturn "Error !! Object can not be read: " + PythonValue + " from " + PythonModule
      EndIf
    Else
      ProcedureReturn "Error !! Object can not be read: " + PythonValue + " from " + PythonModule
    EndIf
  EndProcedure
  
  Procedure.b Python_SetItem(PythonValue.s, Insert.s, PythonModule.s = "__main__")
    Protected *pModule.PythonObject
    *pModule = PythonImport_AddModule(PythonModule)
    If *pModule
      Python_RunString(PythonValue + "=" + Insert)
      ProcedureReturn #True
    Else
      ProcedureReturn #False
    EndIf
  EndProcedure
  
EndModule

;-Main
Global pystring.s = "", Answer.s = ""
OpenConsole()
pystring = "global v"+#CRLF$
pystring = "v = '?'"+#CRLF$
pystring + "def test(p1):"+#CRLF$
pystring + " print('Hello from Python.')"+#CRLF$
pystring + " global v"+#CRLF$
pystring + " v = 10.2+4"+#CRLF$
pystring + " return p1"+#CRLF$ ;Auto-Convert to String!
;pystring + "v = test(149)"+#CRLF$

EasyPython::Python_Init()
PrintN(EasyPython::Python_GetVersion())
EasyPython::Python_RunString(pystring)
Answer = EasyPython::Python_GetFunction("test", "Great!")
PrintN(Answer)
EasyPython::Python_RunString("print('Hellllloooo!!!!')")

PrintN(EasyPython::Python_GetItem("v"))
EasyPython::Python_SetItem("v", "100")
PrintN(EasyPython::Python_GetItem("v"))

EasyPython::Python_RunString("v = v + 50") ;This is how it works better.
PrintN(EasyPython::Python_GetItem("v"))

EasyPython::Python_CallScript(0, GetCurrentDirectory()+"test.py")
Answer = EasyPython::Python_GetFunction("ok","")
Answer = EasyPython::Python_GetFunction("ok2","78|2")
PrintN(Answer)
Input()
EasyPython::Python_Close()
CloseConsole()

UPDATE!!!
Post Reply