forked from Alexey-T/Python-for-Lazarus
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathChanges.txt
1249 lines (1142 loc) · 72.6 KB
/
Changes.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
This is the list of all changes since the first release:
----------------------------------------------------------------------
1.2 error handling in run component
----------------------------------------------------------------------
1.3 Inserted functionality and definitions got from
Grzegorz Makarewicz
http://www.mikroplan.com.pl/home/mak/python
Thank you for permission and help!
----------------------------------------------------------------------
1.4 Cleaning up, eliminating German comments, further tests
Inserted some ideas from Andrew Robinson,
----------------------------------------------------------------------
1.5 Initialization String, some minor functionalities
----------------------------------------------------------------------
2.0 18/12/1997
Extended by Morgan Martinet ([email protected])
The architecture of the system was changed a lot !
See the text files (Documentation and tutorial) for more infos.
* Works with Python 1.5 Beta 2
* Renamed unit as PythonEngine
* Cleaned the formatting of the source code
* Reorganized some parts of the source
* Reorganized the content of the components
* Used exceptions instead of error variables
* Suppressed the script, methods and InitModule of TPytRun,
because there are new components for that.
* We use the ExitProcess function instead of Halt, because
Halt does not unload the Dlls before it leaves.
* When defining methods, there's no need to add a blank method
for the last one, because we allways allocate n+1 methods,
and the new allocated data is allways cleared.
* Renamed classes, in order to avoid name conflicts
with the previous components, which can coexist:
TDynDll --> TDynamicDll
TPytDll --> TPythonInterface
TPytRun --> TPythonEngine (It hosts the interpreter)
* Added components
TEngineClient
TMethodsContainer
TPythonType --> Lets you create a new Type object
TPythonModule --> Lets you create a new module
TPythonDelphiVar --> Lets you create Python variables
that are bound to Delphi.
TPythonOutput --> Works as a console for displaying
Python outputs.
----------------------------------------------------------------------
2.01
* Py_BuildValue modified to support floats thanks to Grzegorz Makarewicz
* Renamed the functions Exec_command -> ExecString
Eval_command -> EvalString
* Added the functions EvalStringAsStr and EvalStringsAsStr
* Added a delay mechanism for the output, in order to let threads write
to output. There are 2 new functions in the module pyio:
SetDelayWrites(1/0) -> (de)activates the delaying
SetMaxLines(val) -> sets the # of lines of the output
* Added 2 functions to convert Python objects to variants and vice versa:
PyObjectAsVariant
VariantAsPyObject
VarRecAsPyObject
* Removed the flag argument of the AddMethod procedure, because it must
be always 1.
* Checked if the VarName attribute of a TPythonDelphiVar does already
exist and raise an exception.
* Added functions CheckSyntax, CheckEvalSyntax, CheckExecSyntax.
* Added functions MakePyTuple, MakePyList,
ArrayToPyTuple, ArrayToPyList, ArrayToPyDict
StringsToPyList, StringsToPyTuple,
PyListToStrings, PyTupleToStrings
* Added a function ReturnNone that returns a
Py_None object, correctly incremented.
* Extended the exception classes in Delphi that map the exceptions of Python.
Now, there's a one to one maping.
----------------------------------------------------------------------
2.02 07/01/1998
* modified Py_BuildValue to handle currencies as python doubles.
* Added method TMethodsContainer.MethodWrap to call Delphi Methods
from Python.
----------------------------------------------------------------------
2.03 09/01/1998
* Removed MethodWrap and added AddDelphiMethod.
I added a new type TDelphiMethod wich will constrain
to declare a valid delphi method to pass to Python.
Now it simplifies the declaration of a method, and it
checks the type of the method passed.
* Added Demo7 to show the new functionality of the Delphi
methods. I show in this demo how to use ArrayToPyTuple
in the getlong2 function.
----------------------------------------------------------------------
2.04 12/01/1998
* Removed the DelphiObject argument of the AddDelphiMethod because
it could be extracted from the DelphiMethod arg (look at the trick !).
----------------------------------------------------------------------
2.05 13/01/1998
* Added a property APIVersion in order to use different versions of
Python.
* Added GetOfObjectCallBack in the MethodCallback.pas and used it in
the AddDelphiMethod.
----------------------------------------------------------------------
2.06 27/01/1998
* Changed how TPythonEngine checks if it already exists.
Now you can open several forms containing each a TPythonEngine,
but you can't drop 2 TPythonEngine on the same form, and when
your application will execute it will check that there's only one
instance of TPythonEngine.
* Added a new property "ExecModule" that lets you specify in which
module your code will be executed. By default it's "__main__".
* Added a new system that lets you create new Python types with
Delphi classes. So, you can use the inheritence and polymorphism
in your Python types ! And it is more easier to build !
* Changed the tutorial, and added a demo8 that shows you how to use
the Delphi classes.
----------------------------------------------------------------------
2.07 02/02/1998
* Added a property "AutoFinalize" to TPythonEngine that enables or not
the call to Py_Finalize in the destructor of TPythonEngine.
It's usefull for the Python modules as Dlls.
* Added a Demo9 to show how to build a Python module as a Dll
and explained it in the tutorial.
* Changed TPythonType so that it automatically creates a variable
containing the type and labelled with the TypeName in its
linked module. Now you can check the type of an object like this:
if type(obj) is spam.Point:
...
----------------------------------------------------------------------
2.08 05/02/1998
* Changed the Input/Output mechanism thanks to Mark Watts.
Renamed TPythonOutput as TPythonInputOutput. It is now a
base class that can be derived in order to output on what
you want (a RichEdit for instance).
There are 2 new events OnSendData and OnReceiveData that let
you send/receive data to/from Python where you want without
deriving a new class. You can use it if you want to send
the output to a file for debuging purposes.
There's a new component TPythonGUIInputOutput that has a property
Output that redirects the output to a RichEdit.
* Changed all demos to reflect the new design.
* Changed tutorial
* Changed Demo9, use module.Initialize instead of module.MakeModule
* cleaned up the "uses" part of the units. Used MessageBox instead of
MessageDlg.
----------------------------------------------------------------------
2.09 08/02/1998
* Added a property "Errors" to TPythonModule that lets you
define python errors and then raise them easily with the
3 methods RaiseError, RaiseErrorFmt and RaiseErrorObj of TPythonModule.
Errors is a collection of TError items.
TError must have a Name (that will be used to define a string
variable into the module). You can define the property "Text"
that will define the content of the string error, if it is of type String.
If you don't define it, then we will use the property "Name" instead.
The property "ErrorType" lets you select between a String error or
a class error. The latter has the advantage of containing instance variables
that provide infos when we catch an error. And because of the class hierarchy,
we can catch a parent class. So, if you define the ErrorType to etClass, then
you can provide the name of the parent class. If it is empty, then there's no
parent ! You can define in which module the parent class can be found (we will
IMPORT this module, so it can be any module, internal or external), else it
will use the module's name of the TPythonModule where the errors are located.
* Changed demo8 to show the use of errors inside an object.
* Updated tutorial.txt
* Updated PyDelphi for the new input/output mechanism.
----------------------------------------------------------------------
2.10 12/02/1998
* When the Name of an Error is changed, then we update all Errors that
are derived from. We check if this Name does not already exist in the
TError collection.
* When the Module of an Error is changed, then we update all Errors that
where referencing it.
* Reactived the AddClient/RemoveClient of a TClientEngine when in
design mode. It seems that there's no crash.
----------------------------------------------------------------------
2.11 19/03/1998
* Corrected a bug in TMethodsContainer.ReallocMethods, because the
function realloc did not clear the new allocated memory.
* Imported function Py_malloc of the python15.dll
* Made procedure TEngineClient.SetEngine virtual
----------------------------------------------------------------------
2.12 06/04/1998
* Added PyFunction_Check to TPythonInterface
* Added FindFunction, EvalPyFunction, EvalFunction and EvalFunctionNoArgs
to TPythonEngine for a more sophisticated interface from Delphi
to Python functions
----------------------------------------------------------------------
======================================================================
----------------------------------------------------------------------
3.00 29/11/1998
Updated for compatibility to Delphi 4:
* TPythonModule.Clients published -> public
* TPythonDelphiVar.VarObject published -> public
* PythonVCLStd not regenerated with VCL Generator to
provide backward compatibility to Delphi 3.
Following points conditional compiled with
$IFDEF DELPHI4_OR_HIGHER (Delphi 4, Compiler VER120):
* Included Definition.Inc to have central conditional defines.
* Python_Controls,Delphi_Controls: uses ImgList added
* Properties TCustomImageList.DragCursor and
TCustomImageList.Dragging removed.
* TDesigner in Python_Forms, Delphi_Forms deleted,
because of missing in Delphi 4
* Added all missing functions from Python/C API Reference Manual
part "8. Initialization, Finalization, and Threads" except
Py_GetCompiler (which is not exported by the DLL). The Py_GetPlatform
is a cheat; the result will always be "win32" (even if running
Delphi 5 under LINUX!). Py_Get(Exec)Prefix return empty strings!
* PyFrameObject updated
* PyInterpreterState and PyThreadState added.
* Added Properties InterpreterState and ThreadState to TPythonEngine
* Added published property InitThreads to PythonEngine.
* Added TPythonThread class.
----------------------------------------------------------------------
3.01 25/05/1999
* Fixed bug in method TPythonModule.Initialize
the event OnInitialize was fired before the module was created
* Added Date support in method TPythonEngine.VariantAsPyObject
Any TDateTime type is converted to a tuple of the form:
(year, month, day, hours, minutes, seconds, milliseconds)
* Added Date support in method TPythonEngine.PyObjectAsVariant
Any tuple of the form:
(year, month, day, hours, minutes, seconds, milliseconds)
is converted in a TDateTime
* Added methods SetVar, GetVar, DeleteVar, SetVarFromVariant,
GetVarAsVariant to the TPythonModule.
They let you easily create/modify/read/delete vars inside a Python module.
* Fixed a RefCount leak in ArrayToPyDict
* Added Demo10 implementing new Python types mapping the VCL components
TTable and TQuery for easy Database access from inside Python.
* Added method FindClient to TPythonEngine
* Fixed small bug in Repr method of a PyObject : it returned the
classname of TPythonEngine instead of this of the TPyObject !
* Fixed bugs with Number, Sequence and Mapping services : they were
not available.
* Fixed missing reference to the function Py_GetBuildInfo in python15.dll
of Python 1.5.2
--> full compatible with last version 1.5.2
* Renamed package Python.dpk to Python_d3.dpk
* Added package for Delphi 4 (Python_d4.dpk)
* Removed references to the TPythonVCLStd when compiling with Delphi 4
----------------------------------------------------------------------
3.02 10/06/1999
* Added global function PythonOK to test if the Python engine is
created and valid.
* Extended the VCL Generator. Now we support the methods call.
----------------------------------------------------------------------
3.03 13/06/1999
* Fixed bug in method TPythonModule.Initialize
The last fix from version 3.01 caused a bug !
the event OnInitialize MUST be fired before the module was created
because it's the place where you add the Module methods !
I restored it as it was and I added a new event : OnAfterInitialize
which lets you define vars inside the module after is has been created.
* Added method InitializeForNewInterpreter to the TPythonModule which
lets you initialize the module again in a new interpreter.
Calling the method initialize could not work because it tested
if the module was already created.
* Added Demo11 which shows you the use of threads inside Python and Delphi.
* Added property ThreadExecMode to TPythonThread class.
----------------------------------------------------------------------
3.04 25/06/1999
* Added dynamic creation of the TRecentFiles component in PyDelphi
in order to avoid its installation.
* Added support of varArray and sequences in the VariantAsPyObject
and PyObjectAsVariant conversion methods of TPythonEngine.
Now a varArray is converted in a Python list of values, and a
Python sequence (a list, a tuple or the like) is converted to
an array of variant.
* Extended Demo10 : added Locate and lookup support in example2
* VCL Generator now supports generation for Delphi 4
----------------------------------------------------------------------
3.05 15/07/1999
* Fixed a bug with TPythonDelphiVar found by Robert Ruehlmann :
could not get type of object (print type(DelphiVar))
----------------------------------------------------------------------
3.06 01/09/1999
* Extended Demo10 : added Range support in example2
* Fixed a bug in Demo10 if we wanted to iterate on an
empty table.
* Fixed a bug in PyObjectAsVariant introduced in 3.04
----------------------------------------------------------------------
3.07 14/09/1999
* In TPythonEngine.Destroy, use Py_Finalize first, before
the finalization of modules, because Python frees objects
stored in modules and this must happen prior to the destruction
of their associated types.
* Rewrote the TPythonDelphiVar using a Delphi class
* Replaced the variant storage in a TPythonDelphiVar with
a Python object. That way you can store any Python object.
* Added two new events to TPythonDelphiVar that let you work
with a Python object instead of a Variant:
OnExtGetValue and OnExtSetValue
* Added new property ValueObject to TPythonDelphiVar, which
lets you access the object stored inside as a PPyObject.
* Updated tutorial.txt
* Updated Demo4
----------------------------------------------------------------------
3.08 16/09/1999
* Added method IsVariantOk to TPythonDelphiVar wich checks if
a variant is one of the standard types (integer, string...)
* Fixed small bug in PyObjectAsVariant method of TPythonEngine,
it didn't return a variant of type varNull if no compatible
type was found, but returned instead a variant whose value
was varNull.
* Changed DateTime support as tuple to reflect the Python format
(year, month, day, hour, min, sec, DayOfWeek, JulianDay, DayLight)
according to a fix proposed by Jose Alberto Hernandis Talens
* Added methods SetToList and ListToSet to TPythonEngine that
let you convert a Delphi set to a Python list, or the opposite.
* Added method IsDelphiObject to TPythonEngine which lets you
test a Python object, in order to know if the underlying object
is a Delphi class (that inherits from TPyObject).
* Fixed a bug found in TPythonEngine.FindFunction:
if the function was not found, Python raised an exception that
was visible only on the next execution of a script.
* Fixed a bug in the finalization of the Python engine:
GetPythonEngine calls TPythonEngine.Initialized to check if Python
is properly initialized, but Initialized calls Py_IsInitialized to
check it, and this functions returns falls after a call to
Py_Finalize.
But Py_Finalize clears all modules and their attributes, which
may call your object destructor, which will use some Python API
but it will raise an exception because it will detect that
Python is no more initialized !
So, I've added a property to TPythonEngine (Finalizing) that
GetPythonEngine will check before Initialized. If it's true
(it is the case only when calling Py_Finalize), then no exception
is raised.
* Added a public method Finalize to TPythonEngine, that lets
you finalize Python yourself, instead of waiting that
the TPythonEngine object is destroyed by the form.
* Extended Demo10
* Checked compatibility with Delphi 5.
It's fine : there was nothing to do ;-)
* Added a package for Delphi 5
----------------------------------------------------------------------
3.09 29/09/1999
* Added event OnPathInitialization to TPythonEngine that will let
you define the Python path in the Windows Registry if it was not
already done.
* Updated tutorial.txt and added a warning in the Demo8
* Added property DocString to the TPythonType that lets you define
a documentation string for your type.
* Added property DocString to the TPythonModule that lets you define
a documentation string for your module.
* Extracted the VCL Generator in an external project.
* Added DocStrings to all types, modules and methods of
the Demo10. Look at example2.
* Added a test with IsDelphiObject in the function
PythonToDelphi.
* Introduced events in VCL Objects of Demo10
----------------------------------------------------------------------
3.10 11/10/1999
* in function pyio_write, we forbid the printing of any other thread
than the main thread, because we could not get to a stable state
in multi-threading.
* Added a docstring for the CreateXXX functions that instantiate
a type XXX.
* Added more events in Demo10
* Added a new property __properties__ to the types mapping the
VCL objects in Demo10, which returns a list of
all available properties. It's like the __methods__ property
but for the properties.
* Added alias "__members__" to "__properties__"
* Added properties InstanceCount, CreateHits, DeleteHits to
the TPythonType, which keep track of the instances allocation.
* Added function GetTypesStats to the pyio module, which will
gather the stats of each type in a list of tuples.
Look at Demo10, example5.
* Added method CheckError to TPythonEngine.
It simply checks if a Python error occurred and if yes, it
prints the Python error and raises a Delphi exception.
* NEW ! NEW ! NEW ! :
Added PythonAtom unit from Olivier Deckmyn ([email protected])
It lets you elegantly access any Python object as an Ole object !!!
You can look at the Demo12 and PythonAtom.hlp
* In Demo10, splitted file pyDatabase.pas in pyDB.pas and pyDBTables.pas
to reflect the VCL unit names.
* NEW ! NEW ! NEW ! :
Added new component TPythonDatabase that implements the VCL units
DB and DBTables for Database access. Look at Demo13.
* Added Demo13 that shows the use of the TPythonDatabase component.
It it the same demo as Demo10, but with the new component.
* Added new package PythonVCL_d3.pkg for the TPythonDatabase component.
* Added new package PythonVCL_d4.pkg for the TPythonDatabase component.
* Added new package PythonVCL_d5.pkg for the TPythonDatabase component.
* Updated readme.txt and tutorial.txt
----------------------------------------------------------------------
3.11 14/10/1999
* Added Demo14 that builds a DLL module from the database components
that will give you access to the database stuff from any Python application,
even from the Python console.
* Updated readme.txt and tutorial.txt
* Added new property "Traceback" to TPythonEngine, which lets you
browse the traceback after the execution of a Python script that
raised an exception. This property is a TPythonTraceback object
that contains a list of Items (TTracebackItem). Each item
contains the filename, lineno and context informations.
This list is automatically refreshed when using TPythonEngine
execution methods, but if you use Python core API, you may call
the Refresh methods at any time (but after the PyErr_Print function),
or you should better call the CheckError method of TPythonEngine.
* TPythonEngine.CheckError refreshes automatically the Traceback.
* In design mode, each new droped EngineClient will automatically find
a TPythonEngine and link to it through the Engine property.
----------------------------------------------------------------------
3.12 24/11/1999
* In TPythonEngine.RemoveClient, we call TPythonEngine.Finalize, if running,
in order to finalize the Python virtual machine BEFORE any TEngineClient
is destroyed by Delphi, because if it occurrs prior to Py_Finalize, the destruction
of a Python object which uses an already destroyed TEngineClient would cause
a memory crash !
* In PyObjectDestructor, we check if PythonOk before call the object destructor.
This avoids crashes with Dlls.
* Made some cleaning in all demos to work properly with Delphi5
* Updated readme.txt and tutorial.txt
* Made an installer that handles all the installation of Python for Delphi
in all versions of Delphi (3 to 5).
----------------------------------------------------------------------
3.13 29/11/1999
* Enhanced checking of date in TPythonEngine.PyObjectAsVariant
* Added Demo15
* Updated tutorial.txt
* Changed representation string of a TPythonDelphiVar
* Removed "Evaluate" button in all demos, except in Demo02.
* In PyDelphi, used TPythonEngine.Traceback and fixed name collapse between
form and type.
----------------------------------------------------------------------
3.14 08/12/1999
* TPythonGUIInputOutput now supports any kind of TCustomMemo, it means that you
can use a TMemo or a TRichEdit.
* Changed Demo1 that uses a TMemo instead of a TReachEdit
* Updated tutorial.txt
* Changed Demo10 and Demo13: added example6 that shows how to subclass any
Python object with a Proxy class.
* Added file deployment.txt that gives some hints on deploying a Delphi application
using Python.
* Added Demo15, that presents 2 examples of interaction between Delphi and Python.
These examples were posted on the Python for Delphi mailing list.
----------------------------------------------------------------------
3.15 25/02/2000
* Enhanced method TPythonEngine.VariantAsPyObject: added support for multi-dimensional
variant arrays (limited to 3 dimensions)
* Added demo17 that shows the use of variant arrays of 2 dimensions.
* Renamed TCallType constants to :
TCallType = (ctSTDCALL, ctCDECL);
in order to avoid a name conflict in C++ Builder.
* Added C++ Builder compilation support, thanks to Sergey A. Kosmakov ([email protected])
* Added Demo18 for C++ Builder: shows how to use the python15.dll in a console app.
* Added Demo19 for C++ Builder: it's a replicate of Demo05
* Added Demo20 for C++ Builder: it's a replicate of Demo08
* Updated tutorial.txt
* Added file C++ Builder Notes.txt
* Updated definition.inc
----------------------------------------------------------------------
3.16 29/11/2000
* Fixed a small bug in CheckRegistry: if the registry key
containing the path was not defined, it tried to write something
even if the event OnPathInitialization was undefined.
Under NT, if not administrator, it would raise an exception as
it's forbidden to write under the HKEY_LOCAL_MACHINE without the
admin rights.
* Changed Dietmar's email: [email protected]
* Added method TPythonEngine.SetProgramArgs which will set the command line arguments transmitted
to the application in the sys.argv list.
* Added C++ Builder 5 packages
* Added new property UseWindowsConsole to TPythonEngine, that lets you use a Windows Text console
instead of a TMemo. If you set it to True, then don't use the RedirectIO !
The main advantage is that it works very well with multi-threading !
It works only if the property is set prior to loading the Python DLL.
* Gene Chiaramonte ([email protected]) fixed a bug in PythonAtom: the order of method arguments
had to be reversed !
* Sigve Tjora ([email protected]) fixed a reference counting bug in PythonAtom.
* Sigve Tjora ([email protected]) made some interesting enhancements in PythonAtom:
- allow pythonAtoms to be passed as arguments to python methods.
Probably PythonDelphi variables can be used to, but it has not been tested.
- allow results from pythonAtom methods to be used as arguments to other pythonAtom methods.
* Sigve Tjora Updated demo12 to demonstrate the use of its new feature.
* Mark Derricutt ([email protected]) added an "Events" collection for defining Python methods
in a TPythonModule. This will ease the declaration of new methods !!!
* Added Demo21 which introduces the new Events collection feature.
* Added Demo22 which presents the new UseWindowsConsole property of TPythonEngine, and
uses the new possibility to extract command line arguments.
We execute a threaded program, which runs fine with the Windows console.
With threaded programs, you must always take care that the calling thread finishes after all
created threads ! This is easily done using the threading module and its "join" method.
Note for Python 1.5.2 version :
if you're using the "threading" module, you should do a TPythonEngine.Finalize in the
OnClose event of your form, otherwise you'll get an access violation ! I don't know why ?
It works fine with the new 1.6 or 2.0 versions.
* Added Demo23 which is basically the same as Demo22, but uses the Delphi Log (since Delphi4) window
for displaying Python output instead of using the Windows console. The main advantage is that you
can scroll the log window, and save its content to a file, but the drawback is that you must
run Delphi !
* Updated tutorial.txt
* allowed the possibility of doing Initialize/Finalize several times in TPythonEngine, in order
to clear the engine memory.
* Added property UseLastKnownVersion to TPythonEngine. If true, PythonEngine will attempt to load
automatically the latest known Python dll.
* Python for Delphi works fine with the latest version 1.6, and with the version 2.0
But I couldn't generate a python20.lib file for the C++ Builder users ! So, just use the component
which uses dynamic linking, and avoid the static linking of the Dll.
* Python for Delphi installs correctly under Windows 2000.
* Fixed a bug in TPythonModule.GetVar. If the var was not found, it would raise a Python exception
the next time you execute a script.
* Igor E. Poteryaev ([email protected]) updated some new API definitions matching the new version 2.0
* Added new methods to the TPyObject class for supporting new API introduced in version 2.0
* Added 2 properties to TPythonEngine: GlobalVars and LocalVars.
You can set a Python dictionary that will be used by the TPythonEngine.Run_CommandAsObject
method. Set properties will increment the reference count of the object.
* Sigve Tjora subclassed TPythonEngine (TAtomPythonEngine) in a new unit AtomPythonEngine.pas,
because he had to use the PythonAtom.pas unit, and we don't want to use Com code in the
PythonEngine.pas unit. The unit is added to the Python_d?.dpk package.
* Stefan Franke [[email protected]] fixed a bug in PythonAtom.pas:
when you called a Python function that returned a result and if you didn't assign the returned
value to a Delphi variable, you would get an access violation.
* Fixed a bug in PyObjectAsVariant: if the Python object was a class instance, that didn't implement
the sequence API, it would raise a Python exception. Now, we check that the sequence API is
properly implemented, and return a Null variant if not.
* Added Demo25 made by Sigve Tjora for demonstrating the use of the TAtomPythonEngine.
----------------------------------------------------------------------
3.17b1 09/07/2001
* Added compatibility with Python 2.1
* Yuri Filimonov ([email protected]) fixed a bug in the asm code of Py_BuildValue: the EBX register was
not correctly restored.
* Added compatibility with Delphi6
* Added unit VarPyth.pas that replaces the PythonAtom.pas, using the new variant custom types of D6.
* In PythonEngine.pas, added functions:
PyObject_DelItem
PyObject_IsInstance
PyObject_IsSubclass
PySequence_Contains
GetMainModule
* Extracted the definition of the PYTHON symbols from PythonEngine.pas to Definition.inc
* Added Demo25 that runs several unit tests for validating the new VarPyth.pas functionality.
It's a good start to look at all that's possible...
----------------------------------------------------------------------
3.17b2 22/07/2001
* Fixed a bug in TPythonEngine.PyObjectAsVariant thanks to [email protected]:
the Python strings containing a zero were truncated when beeing converted
to a variant.
* in PythonEngine.pas:
- added method TPythonEngine.PySequence_DelSlice
- added var TPythonInterface.Py_OptimizeFlag
- added var TPythonInterface.Py_InteractiveFlag
- added var TPythonInterface.Py_NoSiteFlag
- added var TPythonInterface.Py_TabcheckFlag
- added var TPythonInterface.Py_UnicodeFlag
- added property TPythonEngine.PyFlags that lets you enable some Python flags very easily,
like Verbose mode, or Optimize, thanks to a thread started in the mailing list.
* in VarPyth.pas:
- added function VarAsPython --> cast a variant into a Python variant.
- added function GetAtom --> compatibility mode with former PythonAtom.pas
you can use the VarPyth unit instead of PythonAtom, and get the same behaviour of PythonAtom
when instanciating the Python variants with the function GetAtom.
Note however, that you must replace all your OleVariant types with Variant.
You can test it on Demo12: in the uses statement, replace PythonAtom with VarPyth,
and declare myAtom as a Variant, instead of OleVariant. That's all!
But if you're instanciating the Python variants with VarPythonCreate, you'll get the new
behaviour, so you can benefit from the 2 worlds, simultaneously!
- added function len --> return the length of a collection. Same as the len function of Python
and same as using the Length property or Length() method.
So, len(obj) = obj.Length = obj.Length()
- added function _type --> return the type object of a Python object
- added function VarIsSameType --> checks if 2 python variants have the same Python type.
- added function VarIsTrue --> return true if the variant is different from zero or None.
This is the same as casting a variant to a boolean.
- added function Ellipsis that can be used in GetSlice or SetSlice, if you don't want to specifiy
explicitly the length of sequence. So, foo.GetSlice(2, Ellipsis) is equivalent with foo[2:]
- added function BuiltinModule that returns the __builtin__ module object, that contains all
the builtin functions that you can use directly:
_hash := BuiltinModule.hash(foo)
- added special method DelSlice for sequence objects, that does the same as: del list[x:y]
----------------------------------------------------------------------
3.17 27/08/2001 (final)
* Added file py21.lib in the Components folder, it's the lib file for Python 2.1 that allows you
to use the C native APIs of the Python dll.
* Updated the C++ demos to use the py21.lib file
* Updated include files with Python 2.1 version.
* Updated file C++ Builder Notes.txt
* Fixed a bug thanks to Gene Chiaramonte: when running an application with no component for Python output,
an exception was raised while closing the form that hosted PythonEngine, because it tried to restore the initial streams,
whereas no redirection was done.
* Added function NewPythonTuple to VarPyth.pas
* Updated Demo25: added a test for the dates.
* Finished update for changes from version 2.1:
- added enum bsRichCompare to set TBasicServices
- added virtual method RichCompare to TPyObject
- added property TypeFlags to TPythonType for setting new behaviours like tpfHaveRichCompare.
----------------------------------------------------------------------
3.18 02/11/2001
* [email protected] fixed a bug in the VarPyth.pas unit: a crash occurred with some
variants used by ref, with an integer value corresponding to the ID of the VarPython custom
variant type.
* Added access to the variable Py_NotImplemented that should be used in the new coercion model of
version 2.1
* Added Kylix support!!! But I have 1 issue:
- the varargs functions don't work in Kylix (cf PyArg_Parse and PyArg_ParseTuple)
* Started converting the demos to cross-platform usage: Demo01, 02, 03, 07, 09 and 25
* Added new beta version 2.2 to the list of the known versions, and started implementing modifications:
changed the record definitions of the PythonType object, and Code object, that caused a problem
for parsing the traceback. Be sure to define the symbol PYTHON22 before including the definition.inc
because I won't set it as a default until the 2.2 becomes official.
Warning! The date module has introduced a new time_struct for storing a date/time value
in new beta version 2.2.
Maybe the traceback has changed also.
* Added file "Kylix Notes.txt"
* Made the code compatible with the last service pack update for Delphi 6.
----------------------------------------------------------------------
3.19 16/11/2001
* Fixed Kylix port issue: the PyArg_Parse and PyArg_ParseTuple now work properly
thanks to [email protected]
* Finished converting the demos to cross-platform usage: Demo04, 05, 06, 08, 11, 16, 17, 21, 22, 23.
Note that the remaining demos are simply not portable (they use TTable or PythonAtom).
* Continued implementation of the news from version 2.2 of Python.
* Fixed some problems when using the PYTHONXX defines, thanks to Andy Bulka ([email protected]).
----------------------------------------------------------------------
3.20 08/01/2002
* Fixed a ifdef bug in PythonEngine.pas
* Fixed a bug in VarPyth.pas: when setting a property of a Python object, the assigned value
was converted from/to a variant, even when it was a VarPython variant!
* Added APIs for Long objects, and compatibility between Python long objects and Int64 variants.
* Used new Python2.2 APIs for true division (/) and floor division (div) inside VarPyth.
You can now override these behaviours inside your TPyObject classes.
* Added Iter and IterNext new services of Python2.2 to TPythonType.
* Added Traverse and Clear new services of Python2.0 to TPythonType (they are used with Garbage collection).
* Added UNICODE support. A Python Unicode string is kept as wide string inside a variant.
A variant is converted into a Python Unicode string only if the symbol PREFER_UNICODE is defined inside the
file definition.inc
Added APIs PyUnicode_FromWideChar, PyUnicode_AsWideChar
Added methods Unicode_check, PyUnicode_AsWideString, PyUnicode_FromWideString
Note that UNICODE was introduced in Python 2.0
Note that it will work under Kylix, but I deactivated it as I've got a bug with the WideString conversions.
* Added function VarPythonEval to VarPyth.pas, that returns a new Python variant from the evaluation of a Python
expression. This is the same as VarPythonCreate(GetPythonEngine.EvalString(MyExpression))
* Ready for the new time_struct object of Python 2.2 that replaces the tuple of 9 items, but that remains compatible
with it.
* Updated the list of Python exceptions, with their Delphi mapping, using version 2.2.
* Updated set of Python flags up to Python 2.2
* Changed the way of loading the latest version of Python when UseLatestKnownVersion is true:
first we always start from the version which PythonForDelphi was compiled for, and if we don't find it we
try to upgrade the version, only if the new version is compatible with the compiled version.
So, if P4D was compiled for Python 1.5.2 it will only look for python15.dll, and won't try to use python22.dll.
If P4D was compiled for Python 2.1.1 it will first look for python21.dll, then for python22.dll as it's compatible.
* Rewrote the way to extract the traceback content by using PyObject_GetAttrString API instead of direct access to
the traceback record object, to avoid compatibility issues between different versions of Python.
* Added PyWeakRef and PyWrapper APIs, from Python 2.2.
* Updated file "Kylix Notes.txt"
----------------------------------------------------------------------
3.21 06/03/2002
* Fixed a compilation problem when using PYTHON15 symbol.
* Added a default implementation of TCriticalSection for Delphi3 that misses the unit SyncObjs.pas.
* Added property DllPath to specify a folder where the Python Dll should be searched. You can define this property
at runtime, using the event OnBeforeLoad.
* Fixed a bug with custom variants and Int64, introduced by the UpdatePack2 of Delphi6.
* Modified installer to let the user choose a default version of Python before compiling the packages.
* Fixed the WideString/Unicode bug in Kylix. In fact, it was not due to Borland but to Python itself! Python on Linux is supposed
to use UCS2 strings, whereas it actually uses UCS4 strings!!!
* Added a new define HAS_MODIFIED_DISPINVOKE to Definition.inc, to distinguish between Delphi6, Kylix1 and Kylix2, as Kylix2 uses
a modified interface of the method DispInvoke of the custom variants, that has a PVarData parameter instead of a
(var xxx : TVarData).
* Updated file "Kylix Notes.txt"
* Modified DispInvoke of the VarPyth unit.
* PythonForDelphi is up and running with the latest versions of Delphi and Kylix (and Python),
but note that there's a problem with Kylix2 (I used the OpenEdition): all compiles and works fine, but the IDE
crashes when a form hosting PythonForDelphi components is closed! I don't know why, as it works fine with Kylix1
and all Delphi versions! I'll have to investigate further...
----------------------------------------------------------------------
3.22 22/03/2002
* Removed a warning when compiling PythonGUIInputOutput.pas, thanks to Mitch Chapman ([email protected])
* Updated Demo25, and allowed it to work with Python2.0 or higher.
----------------------------------------------------------------------
3.23 20/10/2002
* Delphi7 Ready.
* Fixed a nasty bug that occurred in some cases, but that should have always occurred. To allow multiple Finalize/Initialize
sequences, I moved the ClearEngine loop from the Finalize method to the Destroy method of TPythonEngine.
It was wrong, because when the TPythonEngine was destroyed it tried to call the ClearEngine method of each
of its clients, that were usually already destroyed! The problem appears only when there are a lot of Python components,
otherwise it seems that the memory allocated for the client component is still available for the process
and thus doesn't cause an access violation. This bug was originally discovered by Dietmar.
* Fixed a memory leak in unit VarPyth.pas, in function VarPythonEval
* Fixed a memory leak in Demo25.
* Problem with Kylix3: I can't get the package to compile because it fails with an internal error.
However if you use the Python units inside a project it will compile without any problem! Anyway, I still
have issues with the components in design time, because Delphi IDE freezes when closing a form hosting the
components. So, it may be a workaround for both problems to dynamically create the Python components.
----------------------------------------------------------------------
3.24 29/01/2003
* Fixed nasty bug that would freeze Kylix2 IDE (and maybe Delphi6/7 in some cases):
in unit PythonGUIInputOutput.pas, method TPythonGUIInputOutput.Notification did not call inherited!
* Fixed bug in PythonEngine.pas, in VariantAsPyObject when called by VarPyth.TPythonVariantType.VarDataToPythonObject.
It caused a variant memory error when doing a dict.SetValue('key', ''); (empty string).
Bug reported by Andy Bulka [[email protected]]
* Added Python 2.3 compatibility:
- new bool type: PyBool_Check, PyBool_FromLong
- new date, time, datetime, delta... types from new datetime module
- new property DatetimeConversionMode in TPythonEngine allowing to decide how a variant containing
a datetime should be converted into a Python object.
Presently there are only 2 modes: the default is dcmToTuple (a tuple containing year, month, day...)
and starting with Python2.3 you get dcmToDatetime that will use the new datetime objects of the
datetime module. I could not set it as default to avoid breaking existing code.
- new exceptions: PyExc_FutureWarning, PyExc_PendingDeprecationWarning, PyExc_UnicodeDecodeError,
PyExc_UnicodeEncodeError, PyExc_UnicodeTranslateError
- new APIs (note that some of them were missing since previous Python versions):
PyType_IsSubtype, PyObject_TypeCheck, PyBaseString_Check
PyObject_GC_Malloc, PyObject_GC_New, PyObject_GC_NewVar, PyObject_GC_Resize,
PyObject_GC_Del, PyObject_GC_Track, PyObject_GC_UnTrack
PyType_IS_GC, PyObject_IS_GC
PySlice_GetIndicesEx, PySlice_Check
PyString_DecodeEscape, PyString_Repr
- new behaviour:
With Python2.3 the following functions return True if the Python object is the expected type or
one of its descendants:
PyString_Check
PyFloat_Check
PyInt_Check
PyLong_Check
PyTuple_Check
PyList_Check
PyDict_Check
PyModule_Check
PyUnicode_Check
To check if a Python object is really (and only) the expected type then use the new functions instead:
PyString_CheckExact
PyFloat_CheckExact
PyInt_CheckExact
PyLong_CheckExact
PyTuple_CheckExact
PyList_CheckExact
PyDict_CheckExact
PyModule_CheckExact
PyUnicode_CheckExact
* in unit VarPyth.pas, added functions:
VarIsSubtypeOf
VarIsPythonDateTime
VarIsPythonDate
VarIsPythonTime
VarIsPythonDateTimeTZ
VarIsPythonDateTimeDelta
VarIsPythonTimeTZ
VarIsPythonTZInfo
VarIsBool
VarIsEnum
DatetimeModule
- updated Demo25 to reflect last additions made to VarPyth.pas
----------------------------------------------------------------------
3.25 5/04/2003
* Added compatibility with Python 2.3b2 that refactored the new datetime module.
* Allowed TPyObject instances to be created without a TPythonType, in order to use them outside
P4D context (give nil as argument). This is a suggestion made by Gert Steyn [[email protected]]
* Fixed a bug in TPythonType.TypeFlagsAsInt where some flags where forgotten
(tpfHeapType, tpfBaseType, tpfReady, tpfReadying, tpfHaveGC)
thanks to jacoboy1234 [[email protected]]
* Added APIs PyObject_GenericGetAttr, PyObject_GenericSetAttr,
PyType_GenericAlloc, PyType_GenericNew, PyType_Ready, PyObject_Free
* Added new class TMembersContainer allowing TPythonType to define members of a type
and added class method RegisterMembers to TPyObject, allowing type objects to define
their members, to be used when subclassing an existing type.
* Added new class TGetSetContainer allowing TPythonType to define properties with
Get/Set accessor functions, and added class method RegisterGetSets to TPyObject,
allowing type objects to define their properties, to be used when
subclassing an existing type.
* Allowed any TPythonType (and related TPyObject class) to become a base type
that may be subclassed within Python.
To use this feature, simply select tpfBaseType in the TypeFlags property of TPythonType,
then override TPyObject.RegisterMembers in your Python/Delphi class and expose each
of your instance member as a MemberDef (call AType.AddMember(...)).
You can override TPyObject.RegisterGetSets in you need to expose properties
with Get/Set accessor functions.
You should not override GetAttr and SetAttr anymore and you should not
select the Basic services flags [bsGetAttr, bsSetAttr].
Instead, simply select the flags [bsGetAttrO, bsSetAttrO] and the class
TPyObject does simply call PyObject_GenericGetAttr in GetAttrO
and PyObject_GenericSetAttr in SetAttrO.
The Python Generic Get/Set functions will use new slots introduced in
the type object for specifying a list of members (class fields),
a list of get/set functions (like properties in Delphi) and a list
of methods. That way a subclass can introduce its own members/get,set/methods
and call the others coming from the base classes.
You can override the new Init method of TPyObject if you want to perform the same kind
of initialization that you would do in the __init__ method of a Python class.
Note however that by default the CreateWith constructor of TPyObject will be called
when instanciating a new subtype, allowing you to get constructor arguments as you
already did with regular types.
Note that for a subtype instance, the memory allocated will come from
Python heap and not from Delphi. So, we have a reserved space inside the subtype
instance where we plug our Delphi class definition. This is tricky but it works!
Note that TPyObject now has a new attribute IsSubType set to True when a subtype
is instanciated.
Note that if tpfBaseType is set, you can now instanciate a type by calling its type
object instead of relying on the CreateXXX function. Ex: p = spam.Point(3, 2)
In that case Python acts as it would create a subtype instance by using the
tp_new slot of your type, but the type pointer given is the one of your TPythonType.
So, your TPyObject instance will have memory allocated by Python (prop PythonAlloc
is true) and the property IsSubType will be set to False.
Note that to enable this double behaviour, I had to change the way a TPyObject is
allocated: I removed the first two fields (ob_refcnt and ob_type) and replaced them
with public properties, and redefined NewInstance and FreeInstance to
allocate a bigger chunk of memory (with Sizeof(PyObject) more) and offseted the
Self pointer to start after the PyObject header (containing the space reserved
for the ob_refcnt and ob_type fields). So, when the ob_refcnt and ob_type properties
access their associated data, they pick it from this extra hidden header.
Note that when using GetSelf, it will return a pointer to the the start of this
hidden header. And the Adjust method will correct Self to move after this header.
Finally, in FreeInstance, we free the memory only if PythonAlloc is False.
A B C
+-------------------++------------------------------------------------------+
| PyObject header || TPyObject class |
+----------+--------++-----------------+------------+----------+------------+
|ob_refcnt |ob_type ||hidden Class Ptr |PythonType |IsSubType |PythonAlloc |
|integer |pointer ||pointer |TPythonType |Boolean |Boolean |
|4 bytes |4 bytes ||4 bytes |4 bytes |1 byte |1 byte |
+----------+--------++-----------------+------------+----------+------------+
^ ^
| |
ptr returned ptr returned by Adjust
by GetSelf
- a Python object must start at A.
- a Delphi class class must start at B
- TPyObject.InstanceSize will return C-B
- Sizeof(TPyObject) will return B-A
- The total memory allocated for a TPyObject instance will be C-A,
even if its InstanceSize is C-B.
- When turning a Python object pointer into a Delphi instance pointer, PythonToDelphi
will offset the pointer from A to B.
- When turning a Delphi instance into a Python object pointer, GetSelf will offset
Self from B to A.
- Properties ob_refcnt and ob_type will call GetSelf to access their data.
Subclassing TPyObject in Delphi (TPyPoint = class(TPyObject))
A B C D
+-------------------++------------------------------------------------------+-----------------+
| PyObject header || TPyObject class | TPyPoint class |
+----------+--------++-----------------+------------+----------+------------+--------+--------+
|ob_refcnt |ob_type ||hidden Class Ptr |PythonType |IsSubType |PythonAlloc |x |y |
|integer |pointer ||pointer |TPythonType |Boolean |Boolean |integer |integer |
|4 bytes |4 bytes ||4 bytes |4 bytes |1 byte |1 byte |4 bytes |4 bytes |
+----------+--------++-----------------+------------+----------+------------+--------+--------+
- TPyPoint.InstanceSize will return D-B
- The total memory allocated for a TPyPoint instance will be D-A
- The Python type object will have D-A in its tp_basicsize slot.
- in RegisterMembers, calling
PythonType.AddMember('x', mtInt, Integer(@TPyPoint(nil).x), mfDefault, 'x coordinate');
will produce an offset of C-A, instead of C-B, because AddMember will add
automatically B-A to the offset.
Subclassing TPyPoint in Python (class MyPoint(spam.Point))
A B C D E
+-------------------++------------------------------------------------------+-----------------+---------+
| PyObject header || TPyObject class | TPyPoint class | MyPoint |
+----------+--------++-----------------+------------+----------+------------+--------+--------+---------+
|ob_refcnt |ob_type ||hidden Class Ptr |PythonType |IsSubType |PythonAlloc |x |y |Dict |
|integer |pointer ||pointer |TPythonType |Boolean |Boolean |integer |integer |pointer |
|4 bytes |4 bytes ||4 bytes |4 bytes |1 byte |1 byte |4 bytes |4 bytes |4 bytes |
+----------+--------++-----------------+------------+----------+------------+--------+--------+---------+
- The total memory allocated for a MyPoint instance will be E-A
- The Python type object will have E-A in its tp_basicsize slot.
- The Python type object will have D-A in its tp_dictoffset slot (it is the tp_basicsize of
the inherited type, accessible through tp_base).
- The memory allocation is done by Python, that also initializes parts A-B and D-E,
leaving us an available space between B and D. That's why we can't have the
ob_refcnt and ob_type fields inside the TPyObject class definition, as they would
appear in the free space available for the parent types and would not be used
by Python. This would not be an issue, except for calculating the exact member offsets.
So, hiding the PyObject header and ensuring this always comes first, makes it consistent
in all cases for the member offsets to remain valid.
* Added Demo26 to show how you can build base types (This is an adaptation of Demo8),
and updated Tutorial.txt for giving some explanations to the new way of building
types allowing subclassing.
* Allowed a TPythonType to be dynamically created after everything has already been
setup. It means that the module hosting the type will effectively have a variable
referencing the new Type object and a CreateXXX function for creating new instances
of that type.
----------------------------------------------------------------------
3.26 6/09/2004
* Added compatibility with new version 2.4 of Python (Alpha presently)
* Added new document "Deploying P4D.PDF" explaining how you can deploy your own version of Python (using a private folder).
* Fixed a bug in PythonEngine.pas: when trying to convert a variant containing an empty string to a Python object,
the application could crash with a Memory error exception.
* Fixed a small memory leak when instanciating TPythonEngine at runtime, without an Owner, then TPythonEngine would leak
and internal TPythonModule used for redirecting I/O. (thanks to [email protected])
* Fixed a problem in demo 16 / Example 1 (missing a __str__ override in the wrapper class)
----------------------------------------------------------------------
3.27 01/12/2004
* added method flush when redirecting IO. This was fix made by Qi Wenmin ([email protected]):
In my work I find a little problem with the RedirectIO feature. I enable the RedirectIO and add a stream handler of logging package to the logger. When I launch the script in Delphi, the engine reports the stream handler has no flush() method. So I make some change with PythonEngine.pas, add the following codes into the code constant in the TPythonEngine.DoRedirectIO method:
* fixed a bug when the datetime module was not deployed, P4D would raise an exception while executing
RedirectIO.
* added new event OnSysPathInit to TPythonEngine. This event is fired immediately after Py_Initialize and
will provide the list object stored in sys.path, containing all the folders used by Python to find
an imported module.
This will allow you to extend the path when you have a custom installation that is not allowed to touch
the windows registry/filesystem.
Example:
procedure TForm1.PythonEngine1SysPathInit(Sender : TObject; PathList : PPyObject);
var
folder : PPyObject;
begin
with GetPythonEngine do
begin
folder := PyString_FromString('c:\myapp\mymodules');
PyList_Append(PathList, folder);
Py_XDecRef(folder);
end;
end;
* fixed a bug: when using a Python iterator, eventhough you caught the stop exception, a 'Stop iteration' message was displayed in the output.
* added function iter to VarPyth.pas that will return an iterator object for the specified container argument.
Example:
var
_iter : Variant;
_value : Variant;
begin
_iter := iter(VarPythonCreate([1, 2, 3, 4], stTuple));
try
while True do
begin
_value := iter.next();
[...]
end;
except
on E: EPyStopIteration do
begin
// End of sequence
end;
end;
end;
* added PyDict_Copy api
* added overloaded ExecStrings/EvalStrings methods that let you provide your own global/local dictionaries.
Note that you can still use the TPythonEngine properties LocalVars and GlobalVars.
* added demo27 showing the possibilities of container indexing:
#index:
s[0]
#slice
s[0:2]
#ellipsis
s[...]
#extended slice
s[0:2:2]
#multidimensional slice: