diff --git a/CHANGELOG.md b/CHANGELOG.md index 2aa1944eb..9afccbf2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ details about the cause of the failure if you need to "downcast" to the implementation class. - BREAKING: Parameters marked with `ParameterAttributes.Out` are no longer returned in addition to the regular method return value (unless they are passed with `ref` or `out` keyword). +- BREAKING: Drop support for the long-deprecated CLR.* prefix. ### Fixed diff --git a/src/runtime/importhook.cs b/src/runtime/importhook.cs index 3f318fd1c..d8f7e4dcc 100644 --- a/src/runtime/importhook.cs +++ b/src/runtime/importhook.cs @@ -124,7 +124,7 @@ internal static void Shutdown() internal static void SaveRuntimeData(RuntimeDataStorage storage) { - // Increment the reference counts here so that the objects don't + // Increment the reference counts here so that the objects don't // get freed in Shutdown. Runtime.XIncref(py_clr_module); Runtime.XIncref(root.pyHandle); @@ -241,12 +241,8 @@ public static IntPtr __import__(IntPtr self, IntPtr args, IntPtr kw) // Check these BEFORE the built-in import runs; may as well // do the Incref()ed return here, since we've already found // the module. - if (mod_name == "clr" || mod_name == "CLR") + if (mod_name == "clr") { - if (mod_name == "CLR") - { - Exceptions.deprecation("The CLR module is deprecated. Please use 'clr'."); - } IntPtr clr_module = GetCLRModule(fromList); if (clr_module != IntPtr.Zero) { @@ -262,51 +258,41 @@ public static IntPtr __import__(IntPtr self, IntPtr args, IntPtr kw) string realname = mod_name; string clr_prefix = null; - if (mod_name.StartsWith("CLR.")) + // 2010-08-15: Always seemed smart to let python try first... + // This shaves off a few tenths of a second on test_module.py + // and works around a quirk where 'sys' is found by the + // LoadImplicit() deprecation logic. + // Turns out that the AssemblyManager.ResolveHandler() checks to see if any + // Assembly's FullName.ToLower().StartsWith(name.ToLower()), which makes very + // little sense to me. + IntPtr res = Runtime.PyObject_Call(py_import, args, kw); + if (res != IntPtr.Zero) { - clr_prefix = "CLR."; // prepend when adding the module to sys.modules - realname = mod_name.Substring(4); - string msg = $"Importing from the CLR.* namespace is deprecated. Please import '{realname}' directly."; - Exceptions.deprecation(msg); - } - else - { - // 2010-08-15: Always seemed smart to let python try first... - // This shaves off a few tenths of a second on test_module.py - // and works around a quirk where 'sys' is found by the - // LoadImplicit() deprecation logic. - // Turns out that the AssemblyManager.ResolveHandler() checks to see if any - // Assembly's FullName.ToLower().StartsWith(name.ToLower()), which makes very - // little sense to me. - IntPtr res = Runtime.PyObject_Call(py_import, args, kw); - if (res != IntPtr.Zero) + // There was no error. + if (fromlist && IsLoadAll(fromList)) { - // There was no error. - if (fromlist && IsLoadAll(fromList)) - { - var mod = ManagedType.GetManagedObject(res) as ModuleObject; - mod?.LoadNames(); - } - return res; - } - // There was an error - if (!Exceptions.ExceptionMatches(Exceptions.ImportError)) - { - // and it was NOT an ImportError; bail out here. - return IntPtr.Zero; + var mod = ManagedType.GetManagedObject(res) as ModuleObject; + mod?.LoadNames(); } + return res; + } + // There was an error + if (!Exceptions.ExceptionMatches(Exceptions.ImportError)) + { + // and it was NOT an ImportError; bail out here. + return IntPtr.Zero; + } - if (mod_name == string.Empty) - { - // Most likely a missing relative import. - // For example site-packages\bs4\builder\__init__.py uses it to check if a package exists: - // from . import _html5lib - // We don't support them anyway - return IntPtr.Zero; - } - // Otherwise, just clear the it. - Exceptions.Clear(); + if (mod_name == string.Empty) + { + // Most likely a missing relative import. + // For example site-packages\bs4\builder\__init__.py uses it to check if a package exists: + // from . import _html5lib + // We don't support them anyway + return IntPtr.Zero; } + // Otherwise, just clear the it. + Exceptions.Clear(); string[] names = realname.Split('.'); @@ -372,7 +358,7 @@ public static IntPtr __import__(IntPtr self, IntPtr args, IntPtr kw) // Add the module to sys.modules Runtime.PyDict_SetItemString(modules, tail.moduleName, tail.pyHandle); - // If imported from CLR add CLR. to sys.modules as well + // If imported from CLR add clr. to sys.modules as well if (clr_prefix != null) { Runtime.PyDict_SetItemString(modules, clr_prefix + tail.moduleName, tail.pyHandle); diff --git a/src/runtime/runtime.cs b/src/runtime/runtime.cs index d9301acdc..4cb8db71f 100644 --- a/src/runtime/runtime.cs +++ b/src/runtime/runtime.cs @@ -492,7 +492,6 @@ private static void ClearClrModules() private static void RemoveClrRootModule() { var modules = PyImport_GetModuleDict(); - PyDictTryDelItem(modules, "CLR"); PyDictTryDelItem(modules, "clr"); PyDictTryDelItem(modules, "clr._extra"); } diff --git a/src/runtime/typemanager.cs b/src/runtime/typemanager.cs index b1403081e..89ccdea4c 100644 --- a/src/runtime/typemanager.cs +++ b/src/runtime/typemanager.cs @@ -176,7 +176,7 @@ internal static IntPtr CreateType(Type impl) internal static IntPtr CreateType(ManagedType impl, Type clrType) { // Cleanup the type name to get rid of funny nested type names. - string name = "CLR." + clrType.FullName; + string name = $"clr.{clrType.FullName}"; int i = name.LastIndexOf('+'); if (i > -1) { diff --git a/src/testing/threadtest.cs b/src/testing/threadtest.cs index 2825c3fef..9c76929b2 100644 --- a/src/testing/threadtest.cs +++ b/src/testing/threadtest.cs @@ -11,8 +11,8 @@ public class ThreadTest private static PyObject module; private static string testmod = - "import CLR\n" + - "from CLR.Python.Test import ThreadTest\n" + + "import clr\n" + + "from Python.Test import ThreadTest\n" + "\n" + "def echostring(value):\n" + " return value\n" + diff --git a/src/tests/test_clrmethod.py b/src/tests/test_clrmethod.py index a6078bece..0c63f9c59 100644 --- a/src/tests/test_clrmethod.py +++ b/src/tests/test_clrmethod.py @@ -14,7 +14,7 @@ def __init__(self): @clr.clrmethod(int, [int]) def test(self, x): return x*2 - + def get_X(self): return self._x def set_X(self, value): diff --git a/src/tests/test_compat.py b/src/tests/test_compat.py deleted file mode 100644 index ec36e3be0..000000000 --- a/src/tests/test_compat.py +++ /dev/null @@ -1,233 +0,0 @@ -# -*- coding: utf-8 -*- -# TODO: Complete removal of methods below. Similar to test_module - -"""Backward-compatibility tests for deprecated features.""" - -import clr -import types - -import pytest - -from .utils import is_clr_class, is_clr_module, is_clr_root_module - - -# Tests for old-style CLR-prefixed module naming. -def test_simple_import(): - """Test simple import.""" - import CLR - assert is_clr_root_module(CLR) - assert CLR.__name__ == 'clr' - - import sys - assert isinstance(sys, types.ModuleType) - assert sys.__name__ == 'sys' - - import http.client - assert isinstance(http.client, types.ModuleType) - assert http.client.__name__ == 'http.client' - - -def test_simple_import_with_alias(): - """Test simple import with aliasing.""" - import CLR as myCLR - assert is_clr_root_module(myCLR) - assert myCLR.__name__ == 'clr' - - import sys as mySys - assert isinstance(mySys, types.ModuleType) - assert mySys.__name__ == 'sys' - - import http.client as myHttplib - assert isinstance(myHttplib, types.ModuleType) - assert myHttplib.__name__ == 'http.client' - - -def test_dotted_name_import(): - """Test dotted-name import.""" - import CLR.System - assert is_clr_module(CLR.System) - assert CLR.System.__name__ == 'System' - - import System - assert is_clr_module(System) - assert System.__name__ == 'System' - - assert System is CLR.System - - import xml.dom - assert isinstance(xml.dom, types.ModuleType) - assert xml.dom.__name__ == 'xml.dom' - - -def test_dotted_name_import_with_alias(): - """Test dotted-name import with aliasing.""" - import CLR.System as myCLRSystem - assert is_clr_module(myCLRSystem) - assert myCLRSystem.__name__ == 'System' - - import System as mySystem - assert is_clr_module(mySystem) - assert mySystem.__name__ == 'System' - - assert mySystem is myCLRSystem - - import xml.dom as myDom - assert isinstance(myDom, types.ModuleType) - assert myDom.__name__ == 'xml.dom' - - -def test_simple_import_from(): - """Test simple 'import from'.""" - from CLR import System - assert is_clr_module(System) - assert System.__name__ == 'System' - - from xml import dom - assert isinstance(dom, types.ModuleType) - assert dom.__name__ == 'xml.dom' - - -def test_simple_import_from_with_alias(): - """Test simple 'import from' with aliasing.""" - from CLR import System as mySystem - assert is_clr_module(mySystem) - assert mySystem.__name__ == 'System' - - from xml import dom as myDom - assert isinstance(myDom, types.ModuleType) - assert myDom.__name__ == 'xml.dom' - - -def test_dotted_name_import_from(): - """Test dotted-name 'import from'.""" - from CLR.System import Xml - assert is_clr_module(Xml) - assert Xml.__name__ == 'System.Xml' - - from CLR.System.Xml import XmlDocument - assert is_clr_class(XmlDocument) - assert XmlDocument.__name__ == 'XmlDocument' - - from xml.dom import pulldom - assert isinstance(pulldom, types.ModuleType) - assert pulldom.__name__ == 'xml.dom.pulldom' - - from xml.dom.pulldom import PullDOM - assert isinstance(PullDOM, type) - assert PullDOM.__name__ == 'PullDOM' - - -def test_dotted_name_import_from_with_alias(): - """Test dotted-name 'import from' with aliasing.""" - from CLR.System import Xml as myXml - assert is_clr_module(myXml) - assert myXml.__name__ == 'System.Xml' - - from CLR.System.Xml import XmlDocument as myXmlDocument - assert is_clr_class(myXmlDocument) - assert myXmlDocument.__name__ == 'XmlDocument' - - from xml.dom import pulldom as myPulldom - assert isinstance(myPulldom, types.ModuleType) - assert myPulldom.__name__ == 'xml.dom.pulldom' - - from xml.dom.pulldom import PullDOM as myPullDOM - assert isinstance(myPullDOM, type) - assert myPullDOM.__name__ == 'PullDOM' - - -def test_from_module_import_star(): - """Test from module import * behavior.""" - clr.AddReference('System.Management') - - count = len(locals().keys()) - m = __import__('CLR.System.Management', globals(), locals(), ['*']) - assert m.__name__ == 'System.Management' - assert is_clr_module(m) - assert len(locals().keys()) > count + 1 - - m2 = __import__('System.Management', globals(), locals(), ['*']) - assert m2.__name__ == 'System.Management' - assert is_clr_module(m2) - assert len(locals().keys()) > count + 1 - - assert m is m2 - - -def test_explicit_assembly_load(): - """Test explicit assembly loading using standard CLR tools.""" - from CLR.System.Reflection import Assembly - from CLR import System - import sys - - assembly = Assembly.LoadWithPartialName('System.Data') - assert assembly is not None - - import CLR.System.Data - assert 'System.Data' in sys.modules - - assembly = Assembly.LoadWithPartialName('SpamSpamSpamSpamEggsAndSpam') - assert assembly is None - - -def test_implicit_load_already_valid_namespace(): - """Test implicit assembly load over an already valid namespace.""" - # In this case, the mscorlib assembly (loaded by default) defines - # a number of types in the System namespace. There is also a System - # assembly, which is _not_ loaded by default, which also contains - # types in the System namespace. The desired behavior is for the - # Python runtime to "do the right thing", allowing types from both - # assemblies to be found in the CLR.System module implicitly. - import CLR.System - assert is_clr_class(CLR.System.UriBuilder) - - -def test_import_non_existant_module(): - """Test import failure for a non-existent module.""" - with pytest.raises(ImportError): - import System.SpamSpamSpam - - with pytest.raises(ImportError): - import CLR.System.SpamSpamSpam - - -def test_lookup_no_namespace_type(): - """Test lookup of types without a qualified namespace.""" - import CLR.Python.Test - import CLR - assert is_clr_class(CLR.NoNamespaceType) - - -def test_module_lookup_recursion(): - """Test for recursive lookup handling.""" - with pytest.raises(ImportError): - from CLR import CLR - - with pytest.raises(AttributeError): - import CLR - _ = CLR.CLR - - -def test_module_get_attr(): - """Test module getattr behavior.""" - import CLR.System as System - - int_type = System.Int32 - assert is_clr_class(int_type) - - module = System.Xml - assert is_clr_module(module) - - with pytest.raises(AttributeError): - _ = System.Spam - - with pytest.raises(TypeError): - _ = getattr(System, 1) - - -def test_multiple_imports(): - # import CLR did raise a Seg Fault once - # test if the Exceptions.warn() method still causes it - for _ in range(100): - import CLR - _ = CLR diff --git a/src/tests/test_exceptions.py b/src/tests/test_exceptions.py index 02d3005aa..7fafeebcb 100644 --- a/src/tests/test_exceptions.py +++ b/src/tests/test_exceptions.py @@ -291,7 +291,7 @@ def test_exception_is_instance_of_system_object(): # classes, we wrap managed exceptions in a general-purpose old-style # class that delegates to the wrapped object. This makes _almost_ # everything work as expected, except that an isinstance check against - # CLR.System.Object will fail for a managed exception (because a new + # System.Object will fail for a managed exception (because a new # style class cannot appear in the __bases__ of an old-style class # without causing a crash in the CPython interpreter). This test is # here mainly to remind me to update the caveat in the documentation diff --git a/src/tests/test_method.py b/src/tests/test_method.py index 344734642..c7859e881 100644 --- a/src/tests/test_method.py +++ b/src/tests/test_method.py @@ -928,7 +928,7 @@ def test_getting_generic_method_binding_does_not_leak_memory(): PlainOldClass().GenericMethod[str] gc.collect() - clr.System.GC.Collect() + System.GC.Collect() processBytesAfterCall = process.memory_info().rss print("Memory consumption (bytes) at end of test: " + str(processBytesAfterCall)) @@ -969,7 +969,7 @@ def test_getting_overloaded_method_binding_does_not_leak_memory(): PlainOldClass().OverloadedMethod.Overloads[int] gc.collect() - clr.System.GC.Collect() + System.GC.Collect() processBytesAfterCall = process.memory_info().rss print("Memory consumption (bytes) at end of test: " + str(processBytesAfterCall)) @@ -1010,7 +1010,7 @@ def test_getting_method_overloads_binding_does_not_leak_memory(): PlainOldClass().OverloadedMethod.Overloads gc.collect() - clr.System.GC.Collect() + System.GC.Collect() processBytesAfterCall = process.memory_info().rss print("Memory consumption (bytes) at end of test: " + str(processBytesAfterCall)) 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