Python 3.5.2 wrapper

Share your advanced PureBasic knowledge/code with the community.
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Python 3.5.2 wrapper

Post by Kwai chang caine »

In the v3.5 the "PyString_AsString" function is replaced :shock:
PYTHON is the HELL :evil:
Apparently, numerous functions change in each new version ... :?

Edit : perhaps a way with "PyArg_Parse" :?:
ImageThe happiness is a road...
Not a destination
infratec
Always Here
Always Here
Posts: 7620
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Python 3.5.2 wrapper

Post by infratec »

Hi,

I added PyArg_Parse() to the wrapper in the firts posting.

Save the following as stringresult.py

Code: Select all

def multiply(a,b):
    print("Will compute", a, "times", b)
    c = 0
    for i in range(0, a):
        c = c + b
    return "Result = " + str(c)

#print(multiply1(4,2))
Then try this (CallPyWithStringResult.pb)

Code: Select all

IncludeFile "Python35.pbi"

If OpenConsole()

  If CountProgramParameters() < 2
    PrintN("Usage: call pythonfile funcname [args]")   
    End 1
  EndIf
 
  If PythonInit()
    Python_Initialize()
   
    Debug ProgramParameter(0)
   
    *pName.PythonObject = PythonUnicode_FromString(ProgramParameter(0))
    ; Error checking of pName left out

    *pModule.PythonObject = PythonImport_Import(*pName)
    Python_DECREF(*pName)
   
    Debug ProgramParameter(1)
   
    If *pModule
      *pFunc.PythonObject = PythonObject_GetAttrString(*pModule, ProgramParameter(1))
      ; pFunc is a new reference
      If *pFunc And PythonCallable_Check(*pFunc)
        *pArgs.PythonObject = PythonTuple_New(CountProgramParameters() - 2)
       
        For i = 0 To CountProgramParameters() - 3
          *pValue.PythonObject = PythonLong_FromLong(Val(ProgramParameter(i + 2)))
          If Not *pValue
            Python_DECREF(*pArgs)
            Python_DECREF(*pModule);
            PrintN("Cannot convert argument")
            End 1
          EndIf
          ; pValue reference stolen here:
          PythonTuple_SetItem(*pArgs, i, *pValue)
        Next i
       
        *pValue.PythonObject = PythonObject_CallObject(*pFunc, *pArgs)
        Python_DECREF(*pArgs)
        If *pValue <> #Null
          *res = #Null
          If PythonArg_Parse(*pValue, "s", @*res) <> 0
            PrintN("Result of call: " + PeekS(*res, -1, #PB_Ascii))
          EndIf
          Python_DECREF(*pValue)
        Else
          Python_DECREF(*pFunc)
          Python_DECREF(*pModule)
          PythonErr_Print()
          PrintN("Call failed")
          End 1
        EndIf
       
      Else
        If PythonErr_Occurred()
          PythonErr_Print()
          PrintN("Cannot find function " + ProgramParameter(1))
        EndIf
      EndIf
     
    Else
      PythonErr_Print()
      PrintN("Failed to load " + ProgramParameter(0))
      End 1
    EndIf
       
    Python_Finalize()
  EndIf
 
  Delay(3000)
 
  CloseConsole()
EndIf
Bernd
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Python 3.5.2 wrapper

Post by Kwai chang caine »

INFRATEC ... i love you !!!!! 8)
That's woks very great !!

You have see...little Kcc try during all a day to follow his MASTER, unfortunately without success :cry:
I'm when even, a little bit happy, because i have found the good word " PyArg_Parse() " at the end :lol:
So the more difficult to do, it's not know a word....it's know how and when use it :mrgreen:

Sincerely, who can thinking to use "PyArg_Parse" word instead "PythonString_AsString" for return string ?? :shock:
Sometime, i wonder if the GODS of programming, always have all his reason :lol:

I'm very exciting, now i understand a little bit all the interest of your splendid code.
You imagine, PB and PYTHON hand in hand, the procedural and OOP in the same application
Like this we can use all the power of PB and PYTHON together !!! it's amazing
Can use the numerous libs of PYTHON in PB, like selenium for exampler, open new horizon....
And also, can create real executable with python.... :wink:

But they are again numerous things i have not really understand :oops:
Thanks to you, i can call a function and return number or string
But, how can i ask to PYTHON to import and use selenium ?

Code: Select all

import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys

browser = webdriver.Firefox()
browser.get('http://www.google.com')

search = browser.find_element_by_name('q')
search.send_keys("google search through python")
search.send_keys(Keys.RETURN) # hit return after you enter search text
time.sleep(5) # sleep for 5 seconds so you can see the results
browser.quit()
You know do this miracle ? :D
ImageThe happiness is a road...
Not a destination
infratec
Always Here
Always Here
Posts: 7620
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Python 3.5.2 wrapper

Post by infratec »

Hi KCC,

I don't know Python and I don't know 'selenium' (is this an element of the periodic system :mrgreen: )
And since I will never have something to do with it, I don't want to look deeper inside.
To much other things on the to do list.
And I'm in hospital for a week so really no chance.

Bernd
jack
Addict
Addict
Posts: 1358
Joined: Fri Apr 25, 2003 11:10 pm

Re: Python 3.5.2 wrapper

Post by jack »

I hope it goes well infratec. :)
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Python 3.5.2 wrapper

Post by Kwai chang caine »

Hospital ??? :shock: i hope it's not serious :cry:
Take care of you, the health is important 8)
Ok no problem, perhaps i found answer on the web, with the Embedded in C :wink:
ImageThe happiness is a road...
Not a destination
User avatar
skinkairewalker
Enthusiast
Enthusiast
Posts: 782
Joined: Fri Dec 04, 2015 9:26 pm

Re: Python 3.5.2 wrapper

Post by skinkairewalker »

hi !

i got some error when import ctypes library ...
follow screenshots >

screenshot1 = http://prntscr.com/devkzm
screenshot2 ( ctypes folderc contents ) = http://prntscr.com/devldl

why ctypes dont Works ?
ccode
User
User
Posts: 99
Joined: Sat Jun 23, 2018 5:21 pm

Re: Python 3.5.2 wrapper

Post by ccode »

Hello!

I know that the thread is already old.
How does it work under a current Linux?
How can I use this to execute entire Python scripts?
ccode
User
User
Posts: 99
Joined: Sat Jun 23, 2018 5:21 pm

Re: Python 3.5.2 wrapper

Post by ccode »

Hello ;)

The use of Python with PureBasic is very ingenious.
But I still have a problem with the use of e.g. "Sys.argv".
The script contains the: "QApplication (sys.argv)"

Code: Select all

;Test!!!

Prototype Py_Initialize()
Prototype.s PyRun_SimpleString(pystr)
Prototype Py_Finalize()

If OpenConsole("Python with PB")
  
  If OpenLibrary(0, "libpython3.6m.so.1.0")
    
    PythonInitialize.Py_Initialize = GetFunction(0, "Py_Initialize")
    PythonRunSimpleString.PyRun_SimpleString = GetFunction(0, "PyRun_SimpleString")
    PythonFinalize.Py_Finalize = GetFunction(0, "Py_Finalize")

    script.s = ""
    PythonInitialize()
    
    ReadFile(0, GetCurrentDirectory()+"pyscript.py")
    Repeat
      script + ReadString(0)+Chr(10)
    Until Eof(0)
    CloseFile(0)
    
    PythonRunSimpleString(UTF8(script))
    PythonFinalize()
    
    CloseLibrary(0)
    
    Delay(3000)
    
  EndIf
  
  CloseConsole()
  
EndIf   
ccode
User
User
Posts: 99
Joined: Sat Jun 23, 2018 5:21 pm

Re: Python 3.5.2 wrapper

Post by ccode »

Ok!

It works out ;)
I just have to change the script like this:

QApplication (["pyscript.py"]) instead of QApplication (sys.argv)

Another problem is now only the internal string return.

But I will solve it hopefully. ;)
ccode
User
User
Posts: 99
Joined: Sat Jun 23, 2018 5:21 pm

Re: Python 3.5.2 wrapper

Post by ccode »

The problem is solved. (Return: Python -UTF8 - Strings)
I just have to switch all functions to p-UTF.
Who would have thought that? ;)

Code: Select all

;Test
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.l
  tp_itemsize.l       ; 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.l;
  
  *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.l
  
  ; 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.l
    tp_frees.l
    tp_maxalloc.l
    *tp_prev
    *tp_next
  CompilerEndIf
EndStructure

Structure PythonObject Align #PB_Structure_AlignC
  *_ob_next
  *_ob_prev
  ob_refcnt.l
  *ob_type._typeobject
EndStructure

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
  If op\ob_refcnt <> 0
    ; Don't know how to do it
  Else
    ; Don't know how to do it
  EndIf
EndMacro

Macro Python_XDECREF(op)
  If op : Python_DECREF(op) : EndIf
EndMacro

Macro Python_CLEAR()
  If op
    *_py_tmp = op
    op = #Null
    Py_DECREF(*_py_tmp)
  EndIf
EndMacro

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-Unicode)
OSPrototype.i Py_GetPythonHome()
OSPrototype Py_SetPath(*String.p-unicode)
OSPrototype.i Py_GetPath()
OSPrototype Py_SetProgramName(*String.p-Unicode)
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.l PyDict_GetItemString(*PyObject, String.p-UTF8)

OSPrototype PyErr_Print()
OSPrototype.l PyErr_Occurred()
OSPrototype PyErr_Clear()

OSPrototype.l PyImport_AddModule(String.p-UTF8)
OSPrototype.i PyImport_Import(*PyObject)

OSPrototype.l PyLong_AsLong(*PyObject)
OSPrototype.l PyLong_FromLong(Value.l)

OSPrototype.i PyString_FromString(String.p-UTF8)

OSPrototype.l PyObject_Repr(exc_type)

OSPrototype.i PyUnicode_AsEncodedString(str_type, String.p-Ascii, Str2.p-Ascii)
OSPrototype.i PyString_AsString(*PyObject)
OSPrototype.i PyString_AsStringAndSize(*PyObject, *buffer, *length)

OSPrototype.i PyBytes_As_C(*PyObject)

OSPrototype.l PyModule_GetDict(*PyObject)

OSPrototype.l PyObject_GetAttrString(*PyObject, String.p-UTF8)
OSPrototype.l PyObject_CallObject(*PyObject1, *pyObject2)

OSPrototype.i PyRun_SimpleString(String.p-UTF8)

OSPrototype.l PyTuple_New(Len.l)
OSPrototype.i PyTuple_SetItem(*PyObject1, Size.l, *PyObject2)

OSPrototype.i PyUnicode_FromString(String.p-UTF8)
OSPrototype.i PyUnicode_FromObject(*PyObject)
OSPrototype.i PyUnicode_AsUnicode(*PyObject)

OSPrototype.i PyUnicode_AsWideCharString(*PyObject, *size)
OSPrototype.i PyUnicode_AsUTF8(*PyObject)

OSPrototype.i PyArg_Parse(*args, format.p-UTF8, *char)

Procedure.i PythonInit()
  
  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 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 PythonImport_Import.PyImport_Import = GetFunction(PythonLib, "PyImport_Import")
    
    Global PythonLong_AsLong.PyLong_AsLong = GetFunction(PythonLib, "PyLong_AsLong")
    Global PythonLong_FromLong.PyLong_FromLong = GetFunction(PythonLib, "PyLong_FromLong")
    
    Global PythonString_FromString.PyString_FromString = GetFunction(PythonLib, "PyString_FromString")
    
    Global PythonBytes_As_C.PyBytes_As_C = GetFunction(PythonLib, "PyBytes_As_C")
    
    Global PythonObject_Repr.PyObject_Repr = GetFunction(PythonLib, "PyObject_Repr")
    
    Global PythonUnicode_AsEncodedString.PyUnicode_AsEncodedString = GetFunction(PythonLib, "PyUnicode_AsEncodedString")
    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_AsWideCharString.PyUnicode_AsWideCharString = GetFunction(PythonLib, "PyUnicode_AsWideCharString")
    Global PythonUnicode_AsUTF8.PyUnicode_AsUTF8 = GetFunction(PythonLib, "PyUnicode_AsUTF8")
    
    Global PythonArg_Parse.PyArg_Parse = GetFunction(PythonLib, "PyArg_Parse")
    
  EndIf
  
  ProcedureReturn PythonLib
EndProcedure


Procedure.s Python_GetProgramFullPath()
  ProcedureReturn PeekS(Pyth_GetProgramFullPath(), -1, #PB_Unicode)
EndProcedure


Procedure.s Python_GetVersion()
  ProcedureReturn PeekS(Pyth_GetVersion(), -1, #PB_Ascii)
EndProcedure


Procedure.s Python_GetPlatform()
  ProcedureReturn PeekS(Pyth_GetPlatform(), -1, #PB_Ascii)
EndProcedure


Procedure.s Python_GetCopyright()
  ProcedureReturn PeekS(Pyth_GetCopyright(), -1, #PB_Ascii)
EndProcedure


Procedure.s Python_GetCompiler()
  ProcedureReturn PeekS(Pyth_GetCompiler(), -1, #PB_Ascii)
EndProcedure


Procedure.s Python_GetBuildInfo()
  ProcedureReturn PeekS(Pyth_GetBuildInfo(), -1, #PB_Ascii)
EndProcedure

Procedure.s Python_GetPythonHome()
  Protected Result$, *String
  
  *String = Pyth_GetPythonHome()
  If *String
    Result$ = PeekS(*String, -1, #PB_Unicode)
  EndIf
  
  ProcedureReturn Result$
EndProcedure


Procedure.s Python_GetPath()
  Protected Result$, *String
  
  *String = Pyth_GetPath()
  If *String
    Result$ = PeekS(*String, -1, #PB_Unicode)
  EndIf
  
  ProcedureReturn Result$
EndProcedure


Procedure.s Python_GetProgramName()
  
  Protected Result$, *String
  
  
  *String = Pyth_GetProgramName()
  If *String
    Result$ = PeekS(*String, -1, #PB_Unicode)
  EndIf
  
  ProcedureReturn Result$
  
EndProcedure


Procedure PythonClose()
  
  If IsLibrary(PythonLib)
    CloseLibrary(PythonLib)
    PythonLib = #Null
  EndIf
  
EndProcedure

Procedure.s Python_Function(PythonString.s, PythonFunction.s, PythonParameter.s)
  Protected pystring.s = ""
  Protected CountParameters = CountString(PythonParameter, "|") + 1
  
  *pModule.PythonObject  = PythonImport_AddModule("__main__")
  PythonRun_SimpleString(PythonString)
  
  If *pModule
    
    *pFunc.PythonObject = PythonObject_GetAttrString(*pModule, PythonFunction)
    
    ; pFunc is a new reference
    If *pFunc And PythonCallable_Check(*pFunc)
      
      *pArgs.PythonObject = PythonTuple_New(CountParameters)
      
      For i = 0 To CountParameters - 1
        Parameter$ = StringField(PythonParameter, i + 1, "|")
        ;*pValue.PythonObject = PythonLong_FromLong(Val(Parameter$))
        *pValue.PythonObject = PythonUnicode_FromString(Parameter$)
        
        If Not *pValue
          Python_DECREF(*pArgs)
          Python_DECREF(*pModule);
          Answer$ = "Error !! Cannot convert argument"
        EndIf
        
        ; pValue reference stolen here:
        PythonTuple_SetItem(*pArgs, i, *pValue)
      Next i
      
      *pValue.PythonObject = PythonObject_CallObject(*pFunc, *pArgs)
      Python_DECREF(*pArgs)
      
      If *pValue <> #Null
        *test = PythonUnicode_AsUTF8(*pValue)
        Answer$ = PeekS(*test,-1,#PB_UTF8)
        Python_DECREF(*pValue)
      Else
        Python_DECREF(*pFunc)
        Python_DECREF(*pModule)
        PythonErr_Print()
        Answer$ = "Error !! Call failed"
      EndIf
      
    Else
      
      If PythonErr_Occurred()
        PythonErr_Print()
        Answer$ = "Cannot find function " + PythonFunction
      EndIf
      
    EndIf
    
  Else
    
    PythonErr_Print()
    Answer$ = "Error !! Failed to load " + PythonFile
    
  EndIf
  
  ProcedureReturn Answer$
  
EndProcedure

If OpenConsole("Python with PB")
  
  If PythonInit()
    
    Define script.s = ""
    
    Python_Initialize()
    
    ;     ReadFile(0, GetCurrentDirectory()+"test.py")
    ;     Repeat
    ;       script + ReadString(0)+Chr(10)
    ;     Until Eof(0)
    ;     CloseFile(0)
    Define pystring.s
    
    pystring = "def test(p):"+#LF$
    pystring + " print('Hello from Python.')"+#LF$
    
    pystring + " return str(p)"+#LF$
    ;pystring + " return str('Hello')"+#LF$
    
    ;pystring + "test(12)"+#LF$
    
    Answer$ = Python_Function(pystring, "test", "Hello/Hallöchen")
    
    If Left(Answer$, 5) <> "Error"
      Debug "Result of call: " + Answer$
    Else
      Debug Answer$
    EndIf
    
    Python_Finalize()
    
    CloseLibrary(0)
    
    Delay(3000)
    
  EndIf
  
  CloseConsole()
  
EndIf
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Python 3.5.2 wrapper

Post by Kwai chang caine »

Hello Ccode :D
That not works here on W10 X64 / v5.61 x86 :|
I have download Python 3.6.6 and 3.6.0 put the "python36.dll" in the same folder that your code
And the console open and close several second after :|
ImageThe happiness is a road...
Not a destination
ccode
User
User
Posts: 99
Joined: Sat Jun 23, 2018 5:21 pm

Re: Python 3.5.2 wrapper

Post by ccode »

Hello!
PythonErr_Print () helps to debug.

Temporary solution.
For other data types as string I have to do further research.

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 = "Error !! The Object must return a string."
        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 = str(10.2+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 + str(50)") ;Temporary solution. For other Data types As string I have To do further research.
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()
@Kwai chang caine
Thanks for your testing.
I have deliberately posted it under the heading "Linux".
Under Windows I have to test.

-Windows:
On Windows, the Python Dll must be 64 bit, or use the x86 version of PureBasic.
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Python 3.5.2 wrapper

Post by Kwai chang caine »

That not works again and always with W10 X64 / v5.61 X86 :|
Can you give to me the link where i can download your X86 "python36.dll" please
ImageThe happiness is a road...
Not a destination
dcr3
Enthusiast
Enthusiast
Posts: 184
Joined: Fri Aug 04, 2017 11:03 pm

Re: Python 3.5.2 wrapper

Post by dcr3 »

Works with python37.dll on my pc.

Links: Either one you only need python37.dll

Installer.25M
https://www.python.org/ftp/python/3.7.0 ... -amd64.exe

Portable.6.6M
https://www.python.org/ftp/python/3.7.0 ... -amd64.zip
Post Reply