Skip to content

Commit 022be19

Browse files
authored
Merge branch 'master' into amos-interop-changes
2 parents 8e1fa20 + 451fae6 commit 022be19

16 files changed

+231
-166
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ This document follows the conventions laid out in [Keep a CHANGELOG][].
1414
- `clr.AddReference` may now throw errors besides `FileNotFoundException`, that provide more
1515
details about the cause of the failure
1616
- `clr.AddReference` no longer adds ".dll" implicitly
17+
- `PyIter(PyObject)` constructor replaced with static `PyIter.GetIter(PyObject)` method
1718

1819
### Fixed
1920

src/embed_tests/TestFinalizer.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,18 @@ public void CollectBasicObject()
8787
Assert.GreaterOrEqual(objectCount, 1);
8888
}
8989

90+
[Test]
91+
public void CollectOnShutdown()
92+
{
93+
MakeAGarbage(out var shortWeak, out var longWeak);
94+
FullGCCollect();
95+
var garbage = Finalizer.Instance.GetCollectedObjects();
96+
Assert.IsNotEmpty(garbage);
97+
PythonEngine.Shutdown();
98+
garbage = Finalizer.Instance.GetCollectedObjects();
99+
Assert.IsEmpty(garbage);
100+
}
101+
90102
private static void MakeAGarbage(out WeakReference shortWeak, out WeakReference longWeak)
91103
{
92104
PyLong obj = new PyLong(1024);

src/perf_tests/Python.PerformanceTests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
</ItemGroup>
2929

3030
<Target Name="GetRuntimeLibBuildOutput" BeforeTargets="Build">
31-
<MSBuild Projects="..\runtime\Python.Runtime.15.csproj" Properties="PYTHONNET_PY3_VERSION=PYTHON35;Configuration=$(Configuration);TargetFramework=net40;Python3Version=PYTHON35;OutputPath=bin\for_perf\">
31+
<MSBuild Projects="..\runtime\Python.Runtime.15.csproj" Properties="PYTHONNET_PY3_VERSION=PYTHON38;Configuration=$(Configuration);TargetFramework=net40;Python3Version=PYTHON38;OutputPath=bin\for_perf\">
3232
<Output TaskParameter="TargetOutputs" ItemName="NewPythonRuntime" />
3333
</MSBuild>
3434
</Target>

src/runtime/pyansistring.cs

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,16 @@ public PyAnsiString(IntPtr ptr) : base(ptr)
1717
}
1818

1919

20+
private static IntPtr FromObject(PyObject o)
21+
{
22+
if (o == null || !IsStringType(o))
23+
{
24+
throw new ArgumentException("object is not a string");
25+
}
26+
Runtime.XIncref(o.obj);
27+
return o.obj;
28+
}
29+
2030
/// <summary>
2131
/// PyString Constructor
2232
/// </summary>
@@ -25,14 +35,14 @@ public PyAnsiString(IntPtr ptr) : base(ptr)
2535
/// An ArgumentException will be thrown if the given object is not
2636
/// a Python string object.
2737
/// </remarks>
28-
public PyAnsiString(PyObject o)
38+
public PyAnsiString(PyObject o) : base(FromObject(o))
2939
{
30-
if (!IsStringType(o))
31-
{
32-
throw new ArgumentException("object is not a string");
33-
}
34-
Runtime.XIncref(o.obj);
35-
obj = o.obj;
40+
}
41+
private static IntPtr FromString(string s)
42+
{
43+
IntPtr val = Runtime.PyString_FromString(s);
44+
PythonException.ThrowIfIsNull(val);
45+
return val;
3646
}
3747

3848

@@ -42,10 +52,8 @@ public PyAnsiString(PyObject o)
4252
/// <remarks>
4353
/// Creates a Python string from a managed string.
4454
/// </remarks>
45-
public PyAnsiString(string s)
55+
public PyAnsiString(string s) : base(FromString(s))
4656
{
47-
obj = Runtime.PyString_FromString(s);
48-
PythonException.ThrowIfIsNull(obj);
4957
}
5058

5159

src/runtime/pydict.cs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,8 @@ public PyDict(IntPtr ptr) : base(ptr)
2929
/// <remarks>
3030
/// Creates a new Python dictionary object.
3131
/// </remarks>
32-
public PyDict()
32+
public PyDict() : base(Runtime.PyDict_New())
3333
{
34-
obj = Runtime.PyDict_New();
3534
if (obj == IntPtr.Zero)
3635
{
3736
throw new PythonException();
@@ -47,14 +46,13 @@ public PyDict()
4746
/// ArgumentException will be thrown if the given object is not a
4847
/// Python dictionary object.
4948
/// </remarks>
50-
public PyDict(PyObject o)
49+
public PyDict(PyObject o) : base(o.obj)
5150
{
51+
Runtime.XIncref(o.obj);
5252
if (!IsDictType(o))
5353
{
5454
throw new ArgumentException("object is not a dict");
5555
}
56-
Runtime.XIncref(o.obj);
57-
obj = o.obj;
5856
}
5957

6058

src/runtime/pyfloat.cs

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ namespace Python.Runtime
44
{
55
/// <summary>
66
/// Represents a Python float object. See the documentation at
7-
/// PY2: https://docs.python.org/2/c-api/float.html
87
/// PY3: https://docs.python.org/3/c-api/float.html
98
/// for details.
109
/// </summary>
@@ -31,14 +30,8 @@ public PyFloat(IntPtr ptr) : base(ptr)
3130
/// ArgumentException will be thrown if the given object is not a
3231
/// Python float object.
3332
/// </remarks>
34-
public PyFloat(PyObject o)
33+
public PyFloat(PyObject o) : base(FromObject(o))
3534
{
36-
if (!IsFloatType(o))
37-
{
38-
throw new ArgumentException("object is not a float");
39-
}
40-
Runtime.XIncref(o.obj);
41-
obj = o.obj;
4235
}
4336

4437

@@ -48,26 +41,45 @@ public PyFloat(PyObject o)
4841
/// <remarks>
4942
/// Creates a new Python float from a double value.
5043
/// </remarks>
51-
public PyFloat(double value)
44+
public PyFloat(double value) : base(FromDouble(value))
45+
{
46+
}
47+
48+
private static IntPtr FromObject(PyObject o)
49+
{
50+
if (o == null || !IsFloatType(o))
51+
{
52+
throw new ArgumentException("object is not a float");
53+
}
54+
Runtime.XIncref(o.obj);
55+
return o.obj;
56+
}
57+
58+
private static IntPtr FromDouble(double value)
5259
{
53-
obj = Runtime.PyFloat_FromDouble(value);
54-
PythonException.ThrowIfIsNull(obj);
60+
IntPtr val = Runtime.PyFloat_FromDouble(value);
61+
PythonException.ThrowIfIsNull(val);
62+
return val;
5563
}
5664

65+
private static IntPtr FromString(string value)
66+
{
67+
using (var s = new PyString(value))
68+
{
69+
IntPtr val = Runtime.PyFloat_FromString(s.obj, IntPtr.Zero);
70+
PythonException.ThrowIfIsNull(val);
71+
return val;
72+
}
73+
}
5774

5875
/// <summary>
5976
/// PyFloat Constructor
6077
/// </summary>
6178
/// <remarks>
6279
/// Creates a new Python float from a string value.
6380
/// </remarks>
64-
public PyFloat(string value)
81+
public PyFloat(string value) : base(FromString(value))
6582
{
66-
using (var s = new PyString(value))
67-
{
68-
obj = Runtime.PyFloat_FromString(s.obj, IntPtr.Zero);
69-
PythonException.ThrowIfIsNull(obj);
70-
}
7183
}
7284

7385

src/runtime/pyint.cs

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -31,27 +31,35 @@ public PyInt(IntPtr ptr) : base(ptr)
3131
/// ArgumentException will be thrown if the given object is not a
3232
/// Python int object.
3333
/// </remarks>
34-
public PyInt(PyObject o)
34+
public PyInt(PyObject o) : base(FromObject(o))
3535
{
36-
if (!IsIntType(o))
36+
}
37+
38+
private static IntPtr FromObject(PyObject o)
39+
{
40+
if (o == null || !IsIntType(o))
3741
{
3842
throw new ArgumentException("object is not an int");
3943
}
4044
Runtime.XIncref(o.obj);
41-
obj = o.obj;
45+
return o.obj;
4246
}
4347

48+
private static IntPtr FromInt(int value)
49+
{
50+
IntPtr val = Runtime.PyInt_FromInt32(value);
51+
PythonException.ThrowIfIsNull(val);
52+
return val;
53+
}
4454

4555
/// <summary>
4656
/// PyInt Constructor
4757
/// </summary>
4858
/// <remarks>
4959
/// Creates a new Python int from an int32 value.
5060
/// </remarks>
51-
public PyInt(int value)
61+
public PyInt(int value) : base(FromInt(value))
5262
{
53-
obj = Runtime.PyInt_FromInt32(value);
54-
PythonException.ThrowIfIsNull(obj);
5563
}
5664

5765

@@ -62,10 +70,8 @@ public PyInt(int value)
6270
/// Creates a new Python int from a uint32 value.
6371
/// </remarks>
6472
[CLSCompliant(false)]
65-
public PyInt(uint value)
73+
public PyInt(uint value) : base(FromLong(value))
6674
{
67-
obj = Runtime.PyInt_FromInt64(value);
68-
PythonException.ThrowIfIsNull(obj);
6975
}
7076

7177

@@ -75,10 +81,15 @@ public PyInt(uint value)
7581
/// <remarks>
7682
/// Creates a new Python int from an int64 value.
7783
/// </remarks>
78-
public PyInt(long value)
84+
public PyInt(long value) : base(FromLong(value))
7985
{
80-
obj = Runtime.PyInt_FromInt64(value);
81-
PythonException.ThrowIfIsNull(obj);
86+
}
87+
88+
private static IntPtr FromLong(long value)
89+
{
90+
IntPtr val = Runtime.PyInt_FromInt64(value);
91+
PythonException.ThrowIfIsNull(val);
92+
return val;
8293
}
8394

8495

@@ -89,10 +100,8 @@ public PyInt(long value)
89100
/// Creates a new Python int from a uint64 value.
90101
/// </remarks>
91102
[CLSCompliant(false)]
92-
public PyInt(ulong value)
103+
public PyInt(ulong value) : base(FromLong((long)value))
93104
{
94-
obj = Runtime.PyInt_FromInt64((long)value);
95-
PythonException.ThrowIfIsNull(obj);
96105
}
97106

98107

@@ -142,16 +151,21 @@ public PyInt(sbyte value) : this((int)value)
142151
}
143152

144153

154+
private static IntPtr FromString(string value)
155+
{
156+
IntPtr val = Runtime.PyInt_FromString(value, IntPtr.Zero, 0);
157+
PythonException.ThrowIfIsNull(val);
158+
return val;
159+
}
160+
145161
/// <summary>
146162
/// PyInt Constructor
147163
/// </summary>
148164
/// <remarks>
149165
/// Creates a new Python int from a string value.
150166
/// </remarks>
151-
public PyInt(string value)
167+
public PyInt(string value) : base(FromString(value))
152168
{
153-
obj = Runtime.PyInt_FromString(value, IntPtr.Zero, 0);
154-
PythonException.ThrowIfIsNull(obj);
155169
}
156170

157171

src/runtime/pyiter.cs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,22 @@ public PyIter(IntPtr ptr) : base(ptr)
2626
}
2727

2828
/// <summary>
29-
/// PyIter Constructor
29+
/// PyIter factory function.
3030
/// </summary>
3131
/// <remarks>
32-
/// Creates a Python iterator from an iterable. Like doing "iter(iterable)" in python.
32+
/// Create a new PyIter from a given iterable. Like doing "iter(iterable)" in python.
3333
/// </remarks>
34-
public PyIter(PyObject iterable)
34+
/// <param name="iterable"></param>
35+
/// <returns></returns>
36+
public static PyIter GetIter(PyObject iterable)
3537
{
36-
obj = Runtime.PyObject_GetIter(iterable.obj);
37-
if (obj == IntPtr.Zero)
38+
if (iterable == null)
3839
{
39-
throw new PythonException();
40+
throw new ArgumentNullException();
4041
}
42+
IntPtr val = Runtime.PyObject_GetIter(iterable.obj);
43+
PythonException.ThrowIfIsNull(val);
44+
return new PyIter(val);
4145
}
4246

4347
protected override void Dispose(bool disposing)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy