Skip to content

Commit e239da6

Browse files
authored
Fix StackOverflow in test_functools (#1508)
* Fix StackOverflow in test_functools * Update test_resource_stdlib * Disable failing test on Mono
1 parent 7687852 commit e239da6

3 files changed

Lines changed: 30 additions & 16 deletions

File tree

Src/IronPython.Modules/_functools.cs

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -193,21 +193,33 @@ public void __setstate__(CodeContext context, [NotNone] PythonTuple state) {
193193
}
194194

195195
public string __repr__(CodeContext context) {
196-
var builder = new StringBuilder();
197-
builder.Append("functools.partial(");
198-
builder.Append(PythonOps.Repr(context, func));
199-
foreach (var x in _args) {
200-
builder.Append(", ");
201-
builder.Append(PythonOps.Repr(context, x));
196+
var infinite = PythonOps.GetAndCheckInfinite(this);
197+
if (infinite == null) {
198+
return "...";
202199
}
203-
foreach (var p in _keywordArgs) {
204-
builder.Append(", ");
205-
builder.Append(p.Key);
206-
builder.Append('=');
207-
builder.Append(PythonOps.Repr(context, p.Value));
200+
201+
int infiniteIndex = infinite.Count;
202+
infinite.Add(this);
203+
try {
204+
var builder = new StringBuilder();
205+
builder.Append("functools.partial(");
206+
builder.Append(PythonOps.Repr(context, func));
207+
foreach (var x in _args) {
208+
builder.Append(", ");
209+
builder.Append(PythonOps.Repr(context, x));
210+
}
211+
foreach (var p in _keywordArgs) {
212+
builder.Append(", ");
213+
builder.Append(p.Key);
214+
builder.Append('=');
215+
builder.Append(PythonOps.Repr(context, p.Value));
216+
}
217+
builder.Append(')');
218+
return builder.ToString();
219+
} finally {
220+
System.Diagnostics.Debug.Assert(infiniteIndex == infinite.Count - 1);
221+
infinite.RemoveAt(infiniteIndex);
208222
}
209-
builder.Append(')');
210-
return builder.ToString();
211223
}
212224

213225
#endregion

Tests/modules/system_related/test_resource_stdlib.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ def load_tests(loader, standard_tests, pattern):
2525
suite.addTest(test.test_resource.ResourceTest('test_linux_constants'))
2626
suite.addTest(test.test_resource.ResourceTest('test_pagesize'))
2727
suite.addTest(test.test_resource.ResourceTest('test_prlimit'))
28+
suite.addTest(test.test_resource.ResourceTest('test_prlimit_refcount'))
2829
suite.addTest(test.test_resource.ResourceTest('test_setrusage_refcount'))
2930
return suite
3031

Tests/test_functools_stdlib.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ def load_tests(loader, standard_tests, pattern):
9090
suite.addTest(test.test_functools.TestPartialC('test_positional'))
9191
suite.addTest(test.test_functools.TestPartialC('test_protection_of_callers_dict_argument'))
9292
#suite.addTest(test.test_functools.TestPartialC('test_recursive_pickle')) # StackOverflowException
93-
#suite.addTest(unittest.expectedFailure(test.test_functools.TestPartialC('test_recursive_repr'))) # StackOverflowException, was: AssertionError: '<CPartialSubclass object at 0x00000000000000C0>' != 'CPartialSubclass(...)'
93+
suite.addTest(test.test_functools.TestPartialC('test_recursive_repr'))
9494
suite.addTest(test.test_functools.TestPartialC('test_repr'))
9595
suite.addTest(unittest.expectedFailure(test.test_functools.TestPartialC('test_setstate'))) # AssertionError: Tuples differ: (<function capture at 0x000000000000008D>, (1,), {'a': 10}, {'attr': []}) != (<function capture at 0x000000000000008D>, (1,), {'a': 10}, {})
9696
suite.addTest(test.test_functools.TestPartialC('test_setstate_errors'))
@@ -117,13 +117,14 @@ def load_tests(loader, standard_tests, pattern):
117117
suite.addTest(test.test_functools.TestPartialCSubclass('test_positional'))
118118
suite.addTest(test.test_functools.TestPartialCSubclass('test_protection_of_callers_dict_argument'))
119119
#suite.addTest(test.test_functools.TestPartialCSubclass('test_recursive_pickle')) # StackOverflowException
120-
#suite.addTest(unittest.expectedFailure(test.test_functools.TestPartialCSubclass('test_recursive_repr'))) # StackOverflowException, was: AssertionError: '<CPartialSubclass object at 0x00000000000000C0>' != 'CPartialSubclass(...)'
120+
suite.addTest(unittest.expectedFailure(test.test_functools.TestPartialCSubclass('test_recursive_repr'))) # AssertionError: 'functools.partial(...)' != 'CPartialSubclass(...)'
121121
suite.addTest(unittest.expectedFailure(test.test_functools.TestPartialCSubclass('test_repr'))) # AssertionError
122122
suite.addTest(unittest.expectedFailure(test.test_functools.TestPartialCSubclass('test_setstate'))) # AssertionError: Tuples differ: (<function capture at 0x000000000000008D>, (1,), {'a': 10}, {'attr': []}) != (<function capture at 0x000000000000008D>, (1,), {'a': 10}, {})
123123
suite.addTest(test.test_functools.TestPartialCSubclass('test_setstate_errors'))
124124
suite.addTest(test.test_functools.TestPartialCSubclass('test_setstate_refcount'))
125125
suite.addTest(unittest.expectedFailure(test.test_functools.TestPartialCSubclass('test_setstate_subclasses'))) # AssertionError: <class 'test.test_functools.MyDict'> is not <class 'dict'>
126-
suite.addTest(test.test_functools.TestPartialCSubclass('test_weakref'))
126+
if not is_mono:
127+
suite.addTest(test.test_functools.TestPartialCSubclass('test_weakref'))
127128
suite.addTest(test.test_functools.TestPartialCSubclass('test_with_bound_and_unbound_methods'))
128129
suite.addTest(test.test_functools.TestPartialMethod('test_abstract'))
129130
suite.addTest(test.test_functools.TestPartialMethod('test_arg_combinations'))

0 commit comments

Comments
 (0)