From 60ba5d743eff14e62f413ae65f0e4ae3b429da4f Mon Sep 17 00:00:00 2001 From: Daniel Abrahamsson Date: Mon, 28 Sep 2020 08:39:38 +0200 Subject: [PATCH 1/2] Ensure only implementers of IEnumerable or IEnumerator are considered Iterable Fixes #1234. --- CHANGELOG.md | 1 + src/runtime/typemanager.cs | 7 +++++++ src/tests/test_class.py | 17 +++++++++++++++++ 3 files changed, 25 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ba1594ca..b0559c43c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ details about the cause of the failure - Fix incorrect dereference of wrapper object in `tp_repr`, which may result in a program crash - Fix incorrect dereference in params array handling - Fix `object[]` parameters taking precedence when should not in overload resolution +- Fixed a bug where all .NET class instances were considered Iterable ## [2.5.0][] - 2020-06-14 diff --git a/src/runtime/typemanager.cs b/src/runtime/typemanager.cs index 04d40a2ba..be3ad1b88 100644 --- a/src/runtime/typemanager.cs +++ b/src/runtime/typemanager.cs @@ -164,6 +164,13 @@ internal static IntPtr CreateType(ManagedType impl, Type clrType) // we want to do this after the slot stuff above in case the class itself implements a slot method InitializeSlots(type, impl.GetType()); + if (!clrType.GetInterfaces().Any(ifc => ifc == typeof(IEnumerable) || ifc == typeof(IEnumerator))) + { + // The tp_iter slot should only be set for enumerable types. + Marshal.WriteIntPtr(type, TypeOffset.tp_iter, IntPtr.Zero); + } + + if (base_ != IntPtr.Zero) { Marshal.WriteIntPtr(type, TypeOffset.tp_base, base_); diff --git a/src/tests/test_class.py b/src/tests/test_class.py index 2f15f35b1..08634fce4 100644 --- a/src/tests/test_class.py +++ b/src/tests/test_class.py @@ -172,6 +172,23 @@ def test_ienumerator_iteration(): for item in chars: assert item in 'test string' +def test_iterable(): + """Test what objects are Iterable""" + from collections.abc import Iterable + from Python.Test import ClassTest + + assert isinstance(System.String.Empty, Iterable) + assert isinstance(ClassTest.GetArrayList(), Iterable) + assert isinstance(ClassTest.GetEnumerator(), Iterable) + assert (not isinstance(ClassTest, Iterable)) + assert (not isinstance(ClassTest(), Iterable)) + + class ShouldBeIterable(ClassTest): + def __iter__(self): + return iter([]) + + assert isinstance(ShouldBeIterable(), Iterable) + def test_override_get_item(): """Test managed subclass overriding __getitem__.""" From cec559cd2d003d06413e6f6b85e6052c11f84544 Mon Sep 17 00:00:00 2001 From: Daniel Abrahamsson Date: Mon, 28 Sep 2020 08:39:38 +0200 Subject: [PATCH 2/2] Add danabr to AUTHORS --- AUTHORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS.md b/AUTHORS.md index 23327f84c..9109c65c2 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -28,6 +28,7 @@ - Christoph Gohlke ([@cgohlke](https://github.com/cgohlke)) - Christopher Bremner ([@chrisjbremner](https://github.com/chrisjbremner)) - Christopher Pow ([@christopherpow](https://github.com/christopherpow)) +- Daniel Abrahamsson ([@danabr](https://github.com/danabr)) - Daniel Fernandez ([@fdanny](https://github.com/fdanny)) - Daniel Santana ([@dgsantana](https://github.com/dgsantana)) - Dave Hirschfeld ([@dhirschfeld](https://github.com/dhirschfeld)) 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