Skip to content

Commit 451fae6

Browse files
koubaalostmsu
andauthored
Remove parameterless PyObject constructor (#1226)
Co-authored-by: Victor <lost@losttech.software>
1 parent ef2e6b4 commit 451fae6

13 files changed

+216
-159
lines changed

CHANGELOG.md

+1
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/runtime/pyansistring.cs

+18-10
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

+3-5
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

+29-17
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

+32-18
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

+10-6
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)

src/runtime/pylist.cs

+27-19
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,16 @@ public PyList(IntPtr ptr) : base(ptr)
2828
internal PyList(BorrowedReference reference) : base(reference) { }
2929

3030

31+
private static IntPtr FromObject(PyObject o)
32+
{
33+
if (o == null || !IsListType(o))
34+
{
35+
throw new ArgumentException("object is not a list");
36+
}
37+
Runtime.XIncref(o.obj);
38+
return o.obj;
39+
}
40+
3141
/// <summary>
3242
/// PyList Constructor
3343
/// </summary>
@@ -36,14 +46,8 @@ internal PyList(BorrowedReference reference) : base(reference) { }
3646
/// ArgumentException will be thrown if the given object is not a
3747
/// Python list object.
3848
/// </remarks>
39-
public PyList(PyObject o)
49+
public PyList(PyObject o) : base(FromObject(o))
4050
{
41-
if (!IsListType(o))
42-
{
43-
throw new ArgumentException("object is not a list");
44-
}
45-
Runtime.XIncref(o.obj);
46-
obj = o.obj;
4751
}
4852

4953

@@ -53,36 +57,40 @@ public PyList(PyObject o)
5357
/// <remarks>
5458
/// Creates a new empty Python list object.
5559
/// </remarks>
56-
public PyList()
60+
public PyList() : base(Runtime.PyList_New(0))
5761
{
58-
obj = Runtime.PyList_New(0);
5962
if (obj == IntPtr.Zero)
6063
{
6164
throw new PythonException();
6265
}
6366
}
6467

65-
66-
/// <summary>
67-
/// PyList Constructor
68-
/// </summary>
69-
/// <remarks>
70-
/// Creates a new Python list object from an array of PyObjects.
71-
/// </remarks>
72-
public PyList(PyObject[] items)
68+
private static IntPtr FromArray(PyObject[] items)
7369
{
7470
int count = items.Length;
75-
obj = Runtime.PyList_New(count);
71+
IntPtr val = Runtime.PyList_New(count);
7672
for (var i = 0; i < count; i++)
7773
{
7874
IntPtr ptr = items[i].obj;
7975
Runtime.XIncref(ptr);
80-
int r = Runtime.PyList_SetItem(obj, i, ptr);
76+
int r = Runtime.PyList_SetItem(val, i, ptr);
8177
if (r < 0)
8278
{
79+
Runtime.Py_DecRef(val);
8380
throw new PythonException();
8481
}
8582
}
83+
return val;
84+
}
85+
86+
/// <summary>
87+
/// PyList Constructor
88+
/// </summary>
89+
/// <remarks>
90+
/// Creates a new Python list object from an array of PyObjects.
91+
/// </remarks>
92+
public PyList(PyObject[] items) : base(FromArray(items))
93+
{
8694
}
8795

8896

0 commit comments

Comments
 (0)