Permalink
Browse files

Port from IronPython2 (#424)

  • Loading branch information...
slide committed Sep 6, 2018
1 parent 5420206 commit 4a4d6027274d1d69181828e8530d03a2aa2db0a5
View
@@ -0,0 +1,28 @@
### Prerequisites
The issue tracker is used to report bugs and request new features, NOT to ask questions.
Questions should be posted to the users mailing list which can be accessed at
https://ironpython.groups.io/g/users.
* [ ] Are you running the latest version?
* [ ] Are you reporting to the correct repository?
* [ ] Did you perform a cursory search?
### Description
[Description of the bug or feature]
### Steps to Reproduce
1. [First Step]
2. [Second Step]
3. [and so on...]
**Expected behavior:** [What you expected to happen]
**Actual behavior:** [What actually happened]
### Versions
You can get this information from executing `ipy -V`.
View
@@ -43,6 +43,18 @@ steps:
msbuild /version
dotnet --info
df -Th
# Dump version info on macOS
- ${{ if eq(parameters.os, 'macOS') }}:
- task: ms-devlabs.utilitytasks.task-Shellpp.Shell++@0
displayName: Version Information
inputs:
type: InlineScript
script: |
# Dump some info about the tools
mono --version
msbuild /version
dotnet --info
- powershell: ./make.ps1
displayName: Build
View
@@ -4,6 +4,7 @@
<add key="globalPackagesFolder" value="./packages" />
</config>
<packageSources>
<add key="nuget.org" value="https://www.nuget.org/api/v2/" />
<add key="nuget.org" value="https://api.nuget.org/api/v3/index.json" />
<add key="nunit.myget.org" value="https://www.myget.org/F/nunit/api/v3/index.json" />
</packageSources>
</configuration>
@@ -338,6 +338,11 @@ public class xmlparser {
case XmlNodeType.Text:
BufferText(xmlReader.Value);
break;
case XmlNodeType.SignificantWhitespace:
case XmlNodeType.Whitespace:
if (xmlReader.Depth > 0)
BufferText(xmlReader.Value);
break;
case XmlNodeType.ProcessingInstruction:
handleProcessingInstruction();
break;
@@ -386,14 +391,15 @@ public class xmlparser {
}
while (xmlReader.MoveToNextAttribute()) {
if (xmlReader.Prefix == "xmlns") {
var prefix = xmlReader.LocalName;
if (namespace_separator != null
&& (xmlReader.Prefix == "xmlns" || xmlReader.Prefix == string.Empty && xmlReader.LocalName == "xmlns")) {
var prefix = xmlReader.Prefix == string.Empty ? string.Empty : xmlReader.LocalName;
var uri = xmlReader.Value;
ns_stack.Push(prefix);
var startNamespaceDeclHandler = StartNamespaceDeclHandler;
if (startNamespaceDeclHandler != null) {
FlushBuffer();
startNamespaceDeclHandler(prefix, uri);
startNamespaceDeclHandler(prefix == string.Empty ? null : prefix, uri);
}
continue;
}
@@ -434,7 +440,7 @@ public class xmlparser {
var endNamespaceDeclHandler = EndNamespaceDeclHandler;
if (endNamespaceDeclHandler != null) {
FlushBuffer();
endNamespaceDeclHandler(prefix);
endNamespaceDeclHandler(prefix == string.Empty ? null : prefix);
}
}
}
@@ -133,7 +133,9 @@ def _find_root():
root = os.getcwd()
test = all([os.path.exists(os.path.join(root, x)) for x in test_dirs])
while not test:
last_root = root
root = os.path.dirname(root)
if root == last_root: raise Exception("Root not found")
test = all([os.path.exists(os.path.join(root, x)) for x in test_dirs])
return root
@@ -278,16 +278,30 @@ public BytesIO(CodeContext/*!*/ context, object initial_bytes=null)
public BigInteger seek(double pos, int whence=0) {
throw PythonOps.TypeError("'float' object cannot be interpreted as an index");
}
public BigInteger seek(int pos, BigInteger whence) => seek(pos, (int)whence);
public BigInteger seek(int pos, double whence) => throw PythonOps.TypeError("integer argument expected, got float");
public BigInteger seek(double pos, [DefaultParameterValue(0)]object whence) => throw PythonOps.TypeError("'float' object cannot be interpreted as an index");
public override BigInteger seek(CodeContext/*!*/ context, BigInteger pos, [DefaultParameterValue(0)]object whence) {
_checkClosed();
int posInt = (int)pos;
if (whence is double || whence is Extensible<double>) {
throw PythonOps.TypeError("integer argument expected, got float");
switch (whence) {
case int v:
return seek(posInt, v);
case Extensible<int> v:
return seek(posInt, v);
case BigInteger v:
return seek(posInt, v);
case Extensible<BigInteger> v:
return seek(posInt, v);
case double _:
case Extensible<double> _:
throw PythonOps.TypeError("integer argument expected, got float");
default:
return seek(posInt, GetInt(whence));
}
return seek(posInt, GetInt(whence));
}
public override bool seekable(CodeContext/*!*/ context) {
@@ -94,7 +94,7 @@ partial class MetaPythonType : MetaPythonObject, IPythonInvokable {
private DynamicMetaObject/*!*/ MakeStandardDotNetTypeCall(DynamicMetaObjectBinder/*!*/ call, Expression/*!*/ codeContext, DynamicMetaObject/*!*/[]/*!*/ args) {
CallSignature signature = BindingHelpers.GetCallSignature(call);
PythonContext state = PythonContext.GetPythonContext(call);
MethodBase[] ctors = CompilerHelpers.GetConstructors(Value.UnderlyingSystemType, state.Binder.PrivateBinding);
MethodBase[] ctors = PythonTypeOps.GetConstructors(Value.UnderlyingSystemType, state.Binder.PrivateBinding);
if (ctors.Length > 0) {
return state.Binder.CallMethod(
@@ -45,7 +45,7 @@ partial class PythonBinder : DefaultBinder {
signature,
contextExpression
),
CompilerHelpers.GetConstructors(t, PrivateBinding),
PythonTypeOps.GetConstructors(t, PrivateBinding),
target.Restrictions.Merge(BindingRestrictions.GetInstanceRestriction(target.Expression, target.Value))
);
}
@@ -463,7 +463,7 @@ partial class PythonBinder : DefaultBinder {
case TrackerTypes.MethodGroup:
return new DynamicMetaObject(ReturnMethodGroup((MethodGroup)memberTracker), BindingRestrictions.Empty); ;
case TrackerTypes.Constructor:
MethodBase[] ctors = CompilerHelpers.GetConstructors(type, privateBinding, true);
MethodBase[] ctors = PythonTypeOps.GetConstructors(type, privateBinding, true);
object val;
if (PythonTypeOps.IsDefaultNew(ctors)) {
if (IsPythonType(type)) {
@@ -51,6 +51,12 @@ public SystemExitException(string message, Exception innerException)
return 0;
} else if (Builtin.isinstance(t[0], TypeCache.Int32)) {
return Converter.ConvertToInt32(t[0]);
} else if (Builtin.isinstance(t[0], TypeCache.BigInteger)) {
var b = Converter.ConvertToBigInteger(t[0]);
if(b > int.MaxValue) {
return -1;
}
return (int)b;
}
otherCode = t[0];
@@ -7,6 +7,7 @@
using System.Diagnostics;
using System.Reflection;
using System.Dynamic;
using System.Linq;
using IronPython.Runtime.Binding;
using IronPython.Runtime.Types;
using Microsoft.Scripting;
@@ -270,7 +271,7 @@ internal static class PythonTypeOps {
return new PythonTypeUserDescriptorSlot(DynamicHelpers.GetPythonTypeFromType(type.Type), true);
case TrackerTypes.Constructor:
return GetConstructor(group[0].DeclaringType, privateBinding);
return GetConstructorFunction(group[0].DeclaringType, privateBinding);
case TrackerTypes.Custom:
return ((PythonCustomTracker)group[0]).GetSlot();
@@ -308,12 +309,36 @@ internal static class PythonTypeOps {
return group;
}
private static BuiltinFunction GetConstructor(Type t, bool privateBinding) {
private static BuiltinFunction GetConstructorFunction(Type t, bool privateBinding) {
BuiltinFunction ctorFunc = InstanceOps.NonDefaultNewInst;
MethodBase[] ctors = CompilerHelpers.GetConstructors(t, privateBinding, true);
MethodBase[] ctors = GetConstructors(t, privateBinding, true);
return GetConstructor(t, ctorFunc, ctors);
}
internal static MethodBase[] GetConstructors(Type t, bool privateBinding, bool includeProtected = false) {
MethodBase[] ctors = CompilerHelpers.GetConstructors(t, privateBinding, includeProtected);
if (t.IsEnum()) {
var enumCtor = typeof(PythonTypeOps).GetDeclaredMethods(nameof(CreateEnum)).Single().MakeGenericMethod(t);
ctors = ctors.Concat(new[] { enumCtor }).ToArray();
}
return ctors;
}
// support for EnumType(number)
private static T CreateEnum<T>(object value) {
if (value == null) {
throw PythonOps.ValueError(
$"None is not a valid {PythonOps.ToString(typeof(T))}"
);
}
try {
return (T)Enum.ToObject(typeof(T), value);
} catch (ArgumentException) {
throw PythonOps.ValueError(
$"{PythonOps.ToString(value)} is not a valid {PythonOps.ToString(typeof(T))}"
);
}
}
internal static bool IsDefaultNew(MethodBase[] targets) {
if (targets.Length == 1) {
@@ -611,6 +611,22 @@ internal PythonType(PythonContext context, PythonType[] baseTypes, Type underlyi
}
}
public object this[string member] {
get {
if (!UnderlyingSystemType.IsEnum) {
throw PythonOps.TypeError("'type' object is not subscriptable");
}
if (member == null) {
throw PythonOps.KeyError(member);
}
try {
return Enum.Parse(UnderlyingSystemType, member);
} catch (ArgumentException) {
throw PythonOps.KeyError(member);
}
}
}
[SpecialName, PropertyMethod, WrapperDescriptor]
public static object Get__module__(CodeContext/*!*/ context, PythonType self) {
PythonTypeSlot pts;
@@ -198,8 +198,8 @@ class CaseExecuter {
proc.Start();
if (testcase.Options.Redirect) {
AsyncStreamReader(proc.StandardOutput, data => Console.Write(data));
AsyncStreamReader(proc.StandardError, data => Console.Error.Write(data));
AsyncStreamReader(proc.StandardOutput, data => NUnit.Framework.TestContext.Out.Write(data));
AsyncStreamReader(proc.StandardError, data => NUnit.Framework.TestContext.Error.Write(data));
}
if (!proc.WaitForExit(testcase.Options.Timeout)) {
@@ -104,6 +104,8 @@ def bootstrap(*, root=None, upgrade=False, user=False,
# Construct the arguments to be passed to the pip command
args = ["install", "--no-index", "--find-links", tmpdir]
if sys.implementation.name == "ironpython":
args += ["--no-compile"]
if root:
args += ["--root", root]
if upgrade:
@@ -111,8 +111,26 @@ def test__BytesIO_readline(self):
def test__BytesIO_readlines(self):
print("TODO")
def test__BytesIO_seek(self):
print("TODO")
ddef test__BytesIO_seek(self):
x = BytesIO()
# these should all succeed
x.seek(0)
x.seek(0L)
x.seek(0, 0)
x.seek(0L, 0)
x.seek(0, 0L)
x.seek(0L, 0L)
# these should all fail
self.assertRaises(TypeError, x.seek, 0, 0.0)
self.assertRaises(TypeError, x.seek, 0L, 0.0)
self.assertRaises(ValueError, x.seek, 0, 1000)
self.assertRaises(ValueError, x.seek, 0L, 1000)
self.assertRaises(OverflowError, x.seek, 0, sys.maxsize+1)
self.assertRaises(OverflowError, x.seek, 0L, sys.maxsize+1)
self.assertRaises(TypeError, x.seek, 0.0)
self.assertRaises(TypeError, x.seek, 0.0, 0)
self.assertRaises(OverflowError, x.seek, sys.maxsize+1)
self.assertRaises(OverflowError, x.seek, sys.maxsize+1, 0)
def test__BytesIO_seekable(self):
print("TODO")
@@ -139,7 +157,7 @@ def test_coverage(self):
'''
#--BytesIO.readinto(array.array(...))
import array
readinto_cases = [
[('c',),
[[],[],[],[],[],[],[],[],[],[]],
@@ -290,7 +308,7 @@ def test_coverage(self):
for a_params, a_expected, b_expected in readinto_cases:
b_list = bytesio_helper()
for i in range(len(b_list)):
a = array.array(*a_params)
b = b_list[i]
@@ -299,4 +317,4 @@ def test_coverage(self):
self.assertEqual(a.tolist(),
a_expected[i])
run_test(__name__)
run_test(__name__)
View
@@ -0,0 +1,58 @@
# Licensed to the .NET Foundation under one or more agreements.
# The .NET Foundation licenses this file to you under the Apache 2.0 License.
# See the LICENSE file in the project root for more information.
from iptest import IronPythonTestCase, run_test, skipUnlessIronPython
class Enum34Test(IronPythonTestCase):
"""check that CLR Enum have simular behavior to Python 3.4 enum"""
def setUp(self):
super(Enum34Test, self).setUp()
self.load_iron_python_test()
@skipUnlessIronPython()
def test_constructor(self):
"""check that enum could be constructed from numeric values"""
from IronPythonTest import DaysInt, DaysShort, DaysLong, DaysSByte, DaysByte, DaysUShort, DaysUInt, DaysULong
enum_types = [DaysInt, DaysShort, DaysLong, DaysSByte, DaysByte, DaysUShort, DaysUInt, DaysULong]
# days go from 0x01 to 0x40
# we add 0x80 as a check for undefined enum member
enum_values = list(range(0, 0x80))
invalid_values = [None, 'invalid', self]
for EnumType in enum_types:
for value in enum_values:
day = EnumType(value)
self.assertEqual(int(day), value)
self.assertTrue(EnumType.Mon < EnumType.Tue)
self.assertEqual(EnumType(), EnumType.None)
self.assertEqual(EnumType(0), EnumType.None)
self.assertEqual(EnumType(1), EnumType.Mon)
self.assertEqual(EnumType(6), EnumType.Tue | EnumType.Wed)
self.assertEqual(EnumType(96), EnumType.Weekend)
for value in invalid_values:
self.assertRaises(ValueError, EnumType, value)
@skipUnlessIronPython()
def test_from_str(self):
"""check that enum could be constructed from str names"""
from IronPythonTest import DaysInt, DaysShort, DaysLong, DaysSByte, DaysByte, DaysUShort, DaysUInt, DaysULong
enum_types = [DaysInt, DaysShort, DaysLong, DaysSByte, DaysByte, DaysUShort, DaysUInt, DaysULong]
for EnumType in enum_types:
self.assertEqual(EnumType['None'], EnumType.None)
self.assertEqual(EnumType['Mon'], EnumType.Mon)
self.assertEqual(EnumType['Weekend'], EnumType.Weekend)
self.assertRaises(SystemError, lambda: EnumType[DaysInt])
self.assertRaises(TypeError, lambda: EnumType[None])
self.assertRaises(TypeError, lambda: EnumType[self])
self.assertRaises(KeyError, lambda: EnumType['invalid'])
run_test(__name__)
Oops, something went wrong.

0 comments on commit 4a4d602

Please sign in to comment.