Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit1d107df

Browse files
authored
Merge branch 'master' into modernize-import-hook
2 parents4d27f6e +0775458 commit1d107df

33 files changed

+820
-299
lines changed

‎CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ This document follows the conventions laid out in [Keep a CHANGELOG][].
1313
- Python operator method will call C# operator method for supported binary and unary operators ([#1324][p1324]).
1414
- Add GetPythonThreadID and Interrupt methods in PythonEngine
1515
- Ability to implement delegates with`ref` and`out` parameters in Python, by returning the modified parameter values in a tuple. ([#1355][i1355])
16+
-`PyType` - a wrapper for Python type objects, that also permits creating new heap types from`TypeSpec`
1617

1718
###Changed
1819
- Drop support for Python 2, 3.4, and 3.5
@@ -37,9 +38,13 @@ when .NET expects an integer [#1342][i1342]
3738
- BREAKING: to call Python from .NET`Runtime.PythonDLL` property must be set to Python DLL name
3839
or the DLL must be loaded in advance. This must be done before calling any other Python.NET functions.
3940
- BREAKING:`PyObject.Length()` now raises a`PythonException` when object does not support a concept of length.
41+
- BREAKING: disabled implicit conversion from C# enums to Python`int` and back.
42+
One must now either use enum members (e.g.`MyEnum.Option`), or use enum constructor
43+
(e.g.`MyEnum(42)` or`MyEnum(42, True)` when`MyEnum` does not have a member with value 42).
4044
- Sign Runtime DLL with a strong name
4145
- Implement loading through`clr_loader` instead of the included`ClrModule`, enables
4246
support for .NET Core
47+
- BREAKING: custom encoders are no longer called for instances of`System.Type`
4348
- Replaced the old`__import__` hook hack with a PEP302-style Meta Path Loader.
4449

4550
###Fixed

‎Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<AssemblyCopyright>Copyright (c) 2006-2020 The Contributors of the Python.NET Project</AssemblyCopyright>
55
<AssemblyCompany>pythonnet</AssemblyCompany>
66
<AssemblyProduct>Python.NET</AssemblyProduct>
7-
<LangVersion>7.3</LangVersion>
7+
<LangVersion>9.0</LangVersion>
88
<IsPackable>false</IsPackable>
99
</PropertyGroup>
1010
<ItemGroup>

‎README.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,10 @@ module:
4545
Embedding Python in .NET
4646
------------------------
4747

48-
- You must set `Runtime.PythonDLL` or `PYTHONNET_PYDLL` environment variable
48+
- You must set `Runtime.PythonDLL`propertyor `PYTHONNET_PYDLL` environment variable
4949
starting with version 3.0, otherwise you will receive `TypeInitializationException`.
50+
Typical values are `python38.dll` (Windows), `libpython3.8.dylib` (Mac),
51+
`libpython3.8.so` (most other *nix).
5052
- All calls to python should be inside a
5153
``using (Py.GIL()) {/* Your code here */}`` block.
5254
- Import python modules using ``dynamic mod = Py.Import("mod")``, then

‎pythonnet/__init__.py

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ def load():
2929
if_LOADED:
3030
return
3131

32-
from .find_libpythonimportlinked_libpython
3332
fromos.pathimportjoin,dirname
3433

3534
if_RUNTIMEisNone:
@@ -38,21 +37,11 @@ def load():
3837
set_default_runtime()
3938

4039
dll_path=join(dirname(__file__),"runtime","Python.Runtime.dll")
41-
libpython=linked_libpython()
42-
43-
iflibpythonand_FFIisNoneandsys.platform!="win32":
44-
# Load and leak libpython handle s.t. the .NET runtime doesn't dlcloses
45-
# it
46-
importposix
47-
48-
importcffi
49-
_FFI=cffi.FFI()
50-
_FFI.dlopen(libpython,posix.RTLD_NODELETE|posix.RTLD_LOCAL)
51-
40+
5241
_LOADER_ASSEMBLY=_RUNTIME.get_assembly(dll_path)
5342

5443
func=_LOADER_ASSEMBLY["Python.Runtime.Loader.Initialize"]
55-
iffunc(f"{libpythonor''}".encode("utf8"))!=0:
44+
iffunc(''.encode("utf8"))!=0:
5645
raiseRuntimeError("Failed to initialize Python.Runtime.dll")
5746

5847
importatexit

‎src/embed_tests/Codecs.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,32 @@ public void IterableDecoderTest()
296296
Assert.DoesNotThrow(()=>{codec.TryDecode(pyList,outintEnumerable);});
297297
CollectionAssert.AreEqual(intEnumerable,newList<object>{1,2,3});
298298
}
299+
300+
// regression for https://github.com/pythonnet/pythonnet/issues/1427
301+
[Ignore("https://github.com/pythonnet/pythonnet/issues/1256")]
302+
[Test]
303+
publicvoidPythonRegisteredDecoder_NoStackOverflowOnSystemType()
304+
{
305+
conststringPyCode=@"
306+
import clr
307+
import System
308+
from Python.Runtime import PyObjectConversions
309+
from Python.Runtime.Codecs import RawProxyEncoder
310+
311+
312+
class ListAsRawEncoder(RawProxyEncoder):
313+
__namespace__ = 'Dummy'
314+
def CanEncode(self, clr_type):
315+
return clr_type.Name == 'IList`1' and clr_type.Namespace == 'System.Collections.Generic'
316+
317+
318+
list_encoder = ListAsRawEncoder()
319+
PyObjectConversions.RegisterEncoder(list_encoder)
320+
321+
system_type = list_encoder.GetType()";
322+
323+
PythonEngine.Exec(PyCode);
324+
}
299325
}
300326

301327
/// <summary>

‎src/embed_tests/TestOperator.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,14 @@ public void SymmetricalOperatorOverloads()
335335
");
336336
}
337337

338+
[Test]
339+
publicvoidEnumOperator()
340+
{
341+
PythonEngine.Exec($@"
342+
from System.IO import FileAccess
343+
c = FileAccess.Read | FileAccess.Write");
344+
}
345+
338346
[Test]
339347
publicvoidOperatorOverloadMissingArgument()
340348
{

‎src/embed_tests/TestPyType.cs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
usingSystem.Text;
2+
3+
usingNUnit.Framework;
4+
5+
usingPython.Runtime;
6+
usingPython.Runtime.Native;
7+
8+
namespacePython.EmbeddingTest
9+
{
10+
publicclassTestPyType
11+
{
12+
[OneTimeSetUp]
13+
publicvoidSetUp()
14+
{
15+
PythonEngine.Initialize();
16+
}
17+
18+
[OneTimeTearDown]
19+
publicvoidDispose()
20+
{
21+
PythonEngine.Shutdown();
22+
}
23+
24+
[Test]
25+
publicvoidCanCreateHeapType()
26+
{
27+
conststringname="nÁmæ";
28+
conststringdocStr="dÁcæ";
29+
30+
usingvardoc=newStrPtr(docStr,Encoding.UTF8);
31+
varspec=newTypeSpec(
32+
name:name,
33+
basicSize:ObjectOffset.Size(Runtime.Runtime.PyTypeType),
34+
slots:newTypeSpec.Slot[]{
35+
new(TypeSlotID.tp_doc,doc.RawPointer),
36+
},
37+
TypeFlags.Default|TypeFlags.HeapType
38+
);
39+
40+
usingvartype=newPyType(spec);
41+
Assert.AreEqual(name,type.GetAttr("__name__").As<string>());
42+
Assert.AreEqual(docStr,type.GetAttr("__doc__").As<string>());
43+
}
44+
}
45+
}

‎src/runtime/Codecs/EnumPyLongCodec.cs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
usingSystem;
2+
3+
namespacePython.Runtime.Codecs
4+
{
5+
[Obsolete]
6+
publicsealedclassEnumPyLongCodec:IPyObjectEncoder,IPyObjectDecoder
7+
{
8+
publicstaticEnumPyLongCodecInstance{get;}=newEnumPyLongCodec();
9+
10+
publicboolCanDecode(PyObjectobjectType,TypetargetType)
11+
{
12+
returntargetType.IsEnum
13+
&&objectType.IsSubclass(newBorrowedReference(Runtime.PyLongType));
14+
}
15+
16+
publicboolCanEncode(Typetype)
17+
{
18+
returntype==typeof(object)||type==typeof(ValueType)||type.IsEnum;
19+
}
20+
21+
publicboolTryDecode<T>(PyObjectpyObj,outTvalue)
22+
{
23+
value=default;
24+
if(!typeof(T).IsEnum)returnfalse;
25+
26+
Typeetype=Enum.GetUnderlyingType(typeof(T));
27+
28+
if(!PyLong.IsLongType(pyObj))returnfalse;
29+
30+
objectresult;
31+
try
32+
{
33+
result=pyObj.AsManagedObject(etype);
34+
}
35+
catch(InvalidCastException)
36+
{
37+
returnfalse;
38+
}
39+
40+
if(Enum.IsDefined(typeof(T),result)||typeof(T).IsFlagsEnum())
41+
{
42+
value=(T)Enum.ToObject(typeof(T),result);
43+
returntrue;
44+
}
45+
46+
returnfalse;
47+
}
48+
49+
publicPyObjectTryEncode(objectvalue)
50+
{
51+
if(valueisnull)returnnull;
52+
53+
varenumType=value.GetType();
54+
if(!enumType.IsEnum)returnnull;
55+
56+
try
57+
{
58+
returnnewPyLong((long)value);
59+
}
60+
catch(InvalidCastException)
61+
{
62+
returnnewPyLong((ulong)value);
63+
}
64+
}
65+
66+
privateEnumPyLongCodec(){}
67+
}
68+
}

‎src/runtime/TypeSpec.cs

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
#nullable enable
2+
usingSystem;
3+
usingSystem.Collections.Generic;
4+
usingSystem.Linq;
5+
usingSystem.Runtime.InteropServices;
6+
7+
namespacePython.Runtime
8+
{
9+
publicclassTypeSpec
10+
{
11+
publicTypeSpec(stringname,intbasicSize,IEnumerable<Slot>slots,TypeFlagsflags,intitemSize=0)
12+
{
13+
this.Name=name??thrownewArgumentNullException(nameof(name));
14+
this.BasicSize=basicSize;
15+
this.Slots=slots.ToArray();
16+
this.Flags=flags;
17+
this.ItemSize=itemSize;
18+
}
19+
publicstringName{get;}
20+
publicintBasicSize{get;}
21+
publicintItemSize{get;}
22+
publicTypeFlagsFlags{get;}
23+
publicIReadOnlyList<Slot>Slots{get;}
24+
25+
[StructLayout(LayoutKind.Sequential)]
26+
publicstructSlot
27+
{
28+
publicSlot(TypeSlotIDid,IntPtrvalue)
29+
{
30+
ID=id;
31+
Value=value;
32+
}
33+
34+
publicTypeSlotIDID{get;}
35+
publicIntPtrValue{get;}
36+
}
37+
}
38+
39+
publicenumTypeSlotID:int
40+
{
41+
mp_ass_subscript=3,
42+
mp_length=4,
43+
mp_subscript=5,
44+
nb_absolute=6,
45+
nb_add=7,
46+
nb_and=8,
47+
nb_bool=9,
48+
nb_divmod=10,
49+
nb_float=11,
50+
nb_floor_divide=12,
51+
nb_index=13,
52+
nb_inplace_add=14,
53+
nb_inplace_and=15,
54+
nb_inplace_floor_divide=16,
55+
nb_inplace_lshift=17,
56+
nb_inplace_multiply=18,
57+
nb_inplace_or=19,
58+
nb_inplace_power=20,
59+
nb_inplace_remainder=21,
60+
nb_inplace_rshift=22,
61+
nb_inplace_subtract=23,
62+
nb_inplace_true_divide=24,
63+
nb_inplace_xor=25,
64+
nb_int=26,
65+
nb_invert=27,
66+
nb_lshift=28,
67+
nb_multiply=29,
68+
nb_negative=30,
69+
nb_or=31,
70+
nb_positive=32,
71+
nb_power=33,
72+
nb_remainder=34,
73+
nb_rshift=35,
74+
nb_subtract=36,
75+
nb_true_divide=37,
76+
nb_xor=38,
77+
sq_ass_item=39,
78+
sq_concat=40,
79+
sq_contains=41,
80+
sq_inplace_concat=42,
81+
sq_inplace_repeat=43,
82+
sq_item=44,
83+
sq_length=45,
84+
sq_repeat=46,
85+
tp_alloc=47,
86+
tp_base=48,
87+
tp_bases=49,
88+
tp_call=50,
89+
tp_clear=51,
90+
tp_dealloc=52,
91+
tp_del=53,
92+
tp_descr_get=54,
93+
tp_descr_set=55,
94+
tp_doc=56,
95+
tp_getattr=57,
96+
tp_getattro=58,
97+
tp_hash=59,
98+
tp_init=60,
99+
tp_is_gc=61,
100+
tp_iter=62,
101+
tp_iternext=63,
102+
tp_methods=64,
103+
tp_new=65,
104+
tp_repr=66,
105+
tp_richcompare=67,
106+
tp_setattr=68,
107+
tp_setattro=69,
108+
tp_str=70,
109+
tp_traverse=71,
110+
tp_members=72,
111+
tp_getset=73,
112+
tp_free=74,
113+
nb_matrix_multiply=75,
114+
nb_inplace_matrix_multiply=76,
115+
am_await=77,
116+
am_aiter=78,
117+
am_anext=79,
118+
/// <remarks>New in 3.5</remarks>
119+
tp_finalize=80,
120+
}
121+
}

‎src/runtime/classmanager.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,17 @@ private static ClassInfo GetClassInfo(Type type)
403403
}
404404
}
405405

406+
// only [Flags] enums support bitwise operations
407+
if(type.IsEnum&&type.IsFlagsEnum())
408+
{
409+
varopsImpl=typeof(EnumOps<>).MakeGenericType(type);
410+
foreach(varopinopsImpl.GetMethods(OpsHelper.BindingFlags))
411+
{
412+
local[op.Name]=1;
413+
}
414+
info=info.Concat(opsImpl.GetMethods(OpsHelper.BindingFlags)).ToArray();
415+
}
416+
406417
// Now again to filter w/o losing overloaded member info
407418
for(i=0;i<info.Length;i++)
408419
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp