diff --git a/src/runtime/Codecs/DecoderGroup.cs b/src/runtime/Codecs/DecoderGroup.cs index cf0ee33e9..5b3d127ad 100644 --- a/src/runtime/Codecs/DecoderGroup.cs +++ b/src/runtime/Codecs/DecoderGroup.cs @@ -30,7 +30,7 @@ public void Add(IPyObjectDecoder item) public bool CanDecode(PyType objectType, Type targetType) => this.decoders.Any(decoder => decoder.CanDecode(objectType, targetType)); /// - public bool TryDecode(PyObject pyObj, out T value) + public bool TryDecode(PyObject pyObj, out T? value) { if (pyObj is null) throw new ArgumentNullException(nameof(pyObj)); @@ -65,7 +65,7 @@ public static class DecoderGroupExtensions /// that can decode from to , /// or null if a matching decoder can not be found. /// - public static IPyObjectDecoder GetDecoder( + public static IPyObjectDecoder? GetDecoder( this IPyObjectDecoder decoder, PyType objectType, Type targetType) { diff --git a/src/runtime/Codecs/EncoderGroup.cs b/src/runtime/Codecs/EncoderGroup.cs index 6c40623ca..32b550eb9 100644 --- a/src/runtime/Codecs/EncoderGroup.cs +++ b/src/runtime/Codecs/EncoderGroup.cs @@ -28,7 +28,7 @@ public void Add(IPyObjectEncoder item) /// public bool CanEncode(Type type) => this.encoders.Any(encoder => encoder.CanEncode(type)); /// - public PyObject TryEncode(object value) + public PyObject? TryEncode(object value) { if (value is null) throw new ArgumentNullException(nameof(value)); diff --git a/src/runtime/CollectionWrappers/IterableWrapper.cs b/src/runtime/CollectionWrappers/IterableWrapper.cs index 2ddcd6190..d30e584d3 100644 --- a/src/runtime/CollectionWrappers/IterableWrapper.cs +++ b/src/runtime/CollectionWrappers/IterableWrapper.cs @@ -35,7 +35,7 @@ public IEnumerator GetEnumerator() iterObject.Dispose(); break; } - yield return iterObject.Current.As(); + yield return iterObject.Current.As()!; } } } diff --git a/src/runtime/CollectionWrappers/ListWrapper.cs b/src/runtime/CollectionWrappers/ListWrapper.cs index 29608bc40..41ccb8fae 100644 --- a/src/runtime/CollectionWrappers/ListWrapper.cs +++ b/src/runtime/CollectionWrappers/ListWrapper.cs @@ -16,7 +16,7 @@ public T this[int index] { var item = Runtime.PyList_GetItem(pyObject, index); var pyItem = new PyObject(item); - return pyItem.As(); + return pyItem.As()!; } set { diff --git a/src/runtime/CustomMarshaler.cs b/src/runtime/CustomMarshaler.cs index 4ba603609..f544756d8 100644 --- a/src/runtime/CustomMarshaler.cs +++ b/src/runtime/CustomMarshaler.cs @@ -74,7 +74,7 @@ public static ICustomMarshaler GetInstance(string cookie) return Instance; } - public static string PtrToStringUni(IntPtr p) + public static string? PtrToStringUni(IntPtr p) { if (p == IntPtr.Zero) { @@ -134,7 +134,7 @@ public static IntPtr Py3UnicodePy2StringtoPtr(string s) /// /// Managed String /// - public static string PtrToPy3UnicodePy2String(IntPtr p) + public static string? PtrToPy3UnicodePy2String(IntPtr p) { return PtrToStringUni(p); } @@ -184,7 +184,7 @@ public override IntPtr MarshalManagedToNative(object managedObj) return mem; } - public static ICustomMarshaler GetInstance(string cookie) + public static ICustomMarshaler GetInstance(string? cookie) { return Instance; } diff --git a/src/runtime/Python.Runtime.csproj b/src/runtime/Python.Runtime.csproj index c90ca38e4..a90aa3aaa 100644 --- a/src/runtime/Python.Runtime.csproj +++ b/src/runtime/Python.Runtime.csproj @@ -60,7 +60,8 @@ + + - diff --git a/src/runtime/ReflectedClrType.cs b/src/runtime/ReflectedClrType.cs index 3b83fb443..93c28fd87 100644 --- a/src/runtime/ReflectedClrType.cs +++ b/src/runtime/ReflectedClrType.cs @@ -53,7 +53,9 @@ internal void Restore(InterDomainContext context) { var cb = context.Storage.GetValue("impl"); - cb.Load(this, context); + Debug.Assert(cb is not null); + + cb!.Load(this, context); Restore(cb); } diff --git a/src/runtime/StateSerialization/CLRWrapperCollection.cs b/src/runtime/StateSerialization/CLRWrapperCollection.cs index 66d5170dd..f9e2654eb 100644 --- a/src/runtime/StateSerialization/CLRWrapperCollection.cs +++ b/src/runtime/StateSerialization/CLRWrapperCollection.cs @@ -1,10 +1,11 @@ using System.Collections.ObjectModel; +using System.Diagnostics.CodeAnalysis; namespace Python.Runtime; public class CLRWrapperCollection : KeyedCollection { - public bool TryGetValue(object key, out CLRMappedItem value) + public bool TryGetValue(object key, [NotNullWhen(true)] out CLRMappedItem? value) { if (Dictionary == null) { diff --git a/src/runtime/StateSerialization/ClassManagerState.cs b/src/runtime/StateSerialization/ClassManagerState.cs index 70bb076cd..093e5d41c 100644 --- a/src/runtime/StateSerialization/ClassManagerState.cs +++ b/src/runtime/StateSerialization/ClassManagerState.cs @@ -3,6 +3,10 @@ namespace Python.Runtime.StateSerialization; +// Workaround for the lack of required properties: https://github.com/dotnet/csharplang/issues/3630 +// Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. +#pragma warning disable CS8618 + [Serializable] internal class ClassManagerState { diff --git a/src/runtime/StateSerialization/ImportHookState.cs b/src/runtime/StateSerialization/ImportHookState.cs index 1ade98dbf..cf87cb18b 100644 --- a/src/runtime/StateSerialization/ImportHookState.cs +++ b/src/runtime/StateSerialization/ImportHookState.cs @@ -3,10 +3,14 @@ namespace Python.Runtime.StateSerialization; +// Workaround for the lack of required properties: https://github.com/dotnet/csharplang/issues/3630 +// Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. +#pragma warning disable CS8618 + [Serializable] internal class ImportHookState { - public PyModule PyCLRModule { get; set; } - public PyObject Root { get; set; } - public Dictionary Modules { get; set; } + public PyModule PyCLRModule { get; init; } + public PyObject Root { get; init; } + public Dictionary Modules { get; init; } } diff --git a/src/runtime/StateSerialization/MaybeMemberInfo.cs b/src/runtime/StateSerialization/MaybeMemberInfo.cs index 0a3fbef69..aa369a5ed 100644 --- a/src/runtime/StateSerialization/MaybeMemberInfo.cs +++ b/src/runtime/StateSerialization/MaybeMemberInfo.cs @@ -7,8 +7,6 @@ namespace Python.Runtime [Serializable] internal struct MaybeMemberInfo : ISerializable where T : MemberInfo { - public static implicit operator MaybeMemberInfo(T ob) => new MaybeMemberInfo(ob); - // .ToString() of the serialized object const string SerializationDescription = "d"; // The ReflectedType of the object @@ -50,8 +48,8 @@ public override string ToString() public MaybeMemberInfo(T fi) { info = fi; - Description = info?.ToString(); - if (info?.DeclaringType is not null) + Description = info.ToString(); + if (info.DeclaringType is not null) Description += " of " + info.DeclaringType; deserializationException = null; } diff --git a/src/runtime/StateSerialization/MaybeMethodBase.cs b/src/runtime/StateSerialization/MaybeMethodBase.cs index e773b8e03..a278df2cf 100644 --- a/src/runtime/StateSerialization/MaybeMethodBase.cs +++ b/src/runtime/StateSerialization/MaybeMethodBase.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Runtime.Serialization; using System.Linq; @@ -21,7 +22,7 @@ internal struct MaybeMethodBase : ISerializable where T: MethodBase public static implicit operator MaybeMethodBase (T? ob) => new (ob); - string name; + string? name; MethodBase? info; [NonSerialized] @@ -48,7 +49,8 @@ public T Value } public T UnsafeValue => (T)info!; - public string Name {get{return name;}} + public string? Name => name; + [MemberNotNullWhen(true, nameof(info))] public bool Valid => info != null; public override string ToString() diff --git a/src/runtime/StateSerialization/MetatypeState.cs b/src/runtime/StateSerialization/MetatypeState.cs index 3c0d55642..4e7a44d40 100644 --- a/src/runtime/StateSerialization/MetatypeState.cs +++ b/src/runtime/StateSerialization/MetatypeState.cs @@ -2,6 +2,10 @@ namespace Python.Runtime.StateSerialization; +// Workaround for the lack of required properties: https://github.com/dotnet/csharplang/issues/3630 +// Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. +#pragma warning disable CS8618 + [Serializable] internal class MetatypeState { diff --git a/src/runtime/StateSerialization/PythonNetState.cs b/src/runtime/StateSerialization/PythonNetState.cs index 66092aa42..771f92ecc 100644 --- a/src/runtime/StateSerialization/PythonNetState.cs +++ b/src/runtime/StateSerialization/PythonNetState.cs @@ -2,12 +2,16 @@ namespace Python.Runtime.StateSerialization; +// Workaround for the lack of required properties: https://github.com/dotnet/csharplang/issues/3630 +// Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. +#pragma warning disable CS8618 + [Serializable] internal class PythonNetState { - public MetatypeState Metatype { get; set; } - public SharedObjectsState SharedObjects { get; set; } - public TypeManagerState Types { get; set; } - public ClassManagerState Classes { get; set; } - public ImportHookState ImportHookState { get; set; } + public MetatypeState Metatype { get; init; } + public SharedObjectsState SharedObjects { get; init; } + public TypeManagerState Types { get; init; } + public ClassManagerState Classes { get; init; } + public ImportHookState ImportHookState { get; init; } } diff --git a/src/runtime/StateSerialization/SharedObjectsState.cs b/src/runtime/StateSerialization/SharedObjectsState.cs index a445c9252..0375007d6 100644 --- a/src/runtime/StateSerialization/SharedObjectsState.cs +++ b/src/runtime/StateSerialization/SharedObjectsState.cs @@ -3,11 +3,15 @@ namespace Python.Runtime.StateSerialization; +// Workaround for the lack of required properties: https://github.com/dotnet/csharplang/issues/3630 +// Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. +#pragma warning disable CS8618 + [Serializable] internal class SharedObjectsState { - public Dictionary InternalStores { get; set; } - public Dictionary Extensions { get; set; } - public RuntimeDataStorage Wrappers { get; set; } - public Dictionary Contexts { get; set; } + public Dictionary InternalStores { get; init; } + public Dictionary Extensions { get; init; } + public RuntimeDataStorage Wrappers { get; init; } + public Dictionary Contexts { get; init; } } diff --git a/src/runtime/StateSerialization/TypeManagerState.cs b/src/runtime/StateSerialization/TypeManagerState.cs index 158579549..7630990ef 100644 --- a/src/runtime/StateSerialization/TypeManagerState.cs +++ b/src/runtime/StateSerialization/TypeManagerState.cs @@ -3,6 +3,10 @@ namespace Python.Runtime.StateSerialization; +// Workaround for the lack of required properties: https://github.com/dotnet/csharplang/issues/3630 +// Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. +#pragma warning disable CS8618 + [Serializable] internal class TypeManagerState { diff --git a/src/runtime/Util.cs b/src/runtime/Util.cs index 6fd467ae7..bbed4ad0a 100644 --- a/src/runtime/Util.cs +++ b/src/runtime/Util.cs @@ -119,13 +119,6 @@ internal static void WriteCLong(BorrowedReference type, int offset, Int64 value) } } - /// - /// Null-coalesce: if parameter is not - /// , return it. Otherwise return . - /// - internal static IntPtr Coalesce(this IntPtr primary, IntPtr fallback) - => primary == IntPtr.Zero ? fallback : primary; - /// /// Gets substring after last occurrence of /// @@ -149,5 +142,14 @@ internal static string ReadStringResource(this System.Reflection.Assembly assemb } public static IEnumerator GetEnumerator(this IEnumerator enumerator) => enumerator; + + public static IEnumerable WhereNotNull(this IEnumerable source) + where T: class + { + foreach (var item in source) + { + if (item is not null) yield return item; + } + } } } diff --git a/src/runtime/assemblymanager.cs b/src/runtime/assemblymanager.cs index e39a9cd73..56c70c13a 100644 --- a/src/runtime/assemblymanager.cs +++ b/src/runtime/assemblymanager.cs @@ -358,7 +358,7 @@ public static List GetNames(string nsname) //Dictionary seen = new Dictionary(); var names = new List(8); - List g = GenericUtil.GetGenericBaseNames(nsname); + List? g = GenericUtil.GetGenericBaseNames(nsname); if (g != null) { foreach (string n in g) diff --git a/src/runtime/classbase.cs b/src/runtime/classbase.cs index 069757b40..9ef7c626c 100644 --- a/src/runtime/classbase.cs +++ b/src/runtime/classbase.cs @@ -67,7 +67,7 @@ public virtual NewReference type_subscript(BorrowedReference idx) return Exceptions.RaiseTypeError(type.DeletedMessage); } - Type target = GenericUtil.GenericForType(type.Value, types.Length); + Type? target = GenericUtil.GenericForType(type.Value, types.Length); if (target != null) { @@ -396,7 +396,7 @@ protected override void OnSave(BorrowedReference ob, InterDomainContext context) context.Storage.AddValue("impl", this); } - protected override void OnLoad(BorrowedReference ob, InterDomainContext context) + protected override void OnLoad(BorrowedReference ob, InterDomainContext? context) { base.OnLoad(ob, context); var gcHandle = GCHandle.Alloc(this); diff --git a/src/runtime/classderived.cs b/src/runtime/classderived.cs index b9b3419de..a39f23bef 100644 --- a/src/runtime/classderived.cs +++ b/src/runtime/classderived.cs @@ -144,7 +144,7 @@ internal static NewReference ToPython(IPythonDerivedType obj) internal static Type CreateDerivedType(string name, Type baseType, BorrowedReference py_dict, - string namespaceStr, + string? namespaceStr, string? assemblyName, string moduleName = "Python.Runtime.Dynamic.dll") { @@ -669,7 +669,7 @@ public class PythonDerivedType /// method binding (i.e. it has been overridden in the derived python /// class) it calls it, otherwise it calls the base method. /// - public static T InvokeMethod(IPythonDerivedType obj, string methodName, string origMethodName, object[] args) + public static T? InvokeMethod(IPythonDerivedType obj, string methodName, string origMethodName, object[] args) { var self = GetPyObj(obj); @@ -776,7 +776,7 @@ public static void InvokeMethodVoid(IPythonDerivedType obj, string methodName, s args); } - public static T InvokeGetProperty(IPythonDerivedType obj, string propertyName) + public static T? InvokeGetProperty(IPythonDerivedType obj, string propertyName) { var self = GetPyObj(obj); diff --git a/src/runtime/clrobject.cs b/src/runtime/clrobject.cs index f3fed3ce2..c178ca459 100644 --- a/src/runtime/clrobject.cs +++ b/src/runtime/clrobject.cs @@ -59,7 +59,7 @@ internal static void Restore(object ob, BorrowedReference pyHandle, InterDomainC co.OnLoad(pyHandle, context); } - protected override void OnLoad(BorrowedReference ob, InterDomainContext context) + protected override void OnLoad(BorrowedReference ob, InterDomainContext? context) { base.OnLoad(ob, context); GCHandle gc = GCHandle.Alloc(this); diff --git a/src/runtime/converterextensions.cs b/src/runtime/converterextensions.cs index 7dfdebcbd..9a7ae5403 100644 --- a/src/runtime/converterextensions.cs +++ b/src/runtime/converterextensions.cs @@ -126,7 +126,7 @@ internal static bool TryDecode(BorrowedReference pyHandle, BorrowedReference pyT Debug.Assert(PyType.IsType(sourceTypeRef)); var pyType = new PyType(sourceTypeRef, prevalidated: true); - IPyObjectDecoder decoder; + IPyObjectDecoder? decoder; lock (decoders) { decoder = decoders.GetDecoder(pyType, targetType); diff --git a/src/runtime/extensiontype.cs b/src/runtime/extensiontype.cs index d583f6710..e3f049e1a 100644 --- a/src/runtime/extensiontype.cs +++ b/src/runtime/extensiontype.cs @@ -95,7 +95,7 @@ public static int tp_clear(BorrowedReference ob) return res; } - protected override void OnLoad(BorrowedReference ob, InterDomainContext context) + protected override void OnLoad(BorrowedReference ob, InterDomainContext? context) { base.OnLoad(ob, context); SetupGc(ob, Runtime.PyObject_TYPE(ob)); diff --git a/src/runtime/fieldobject.cs b/src/runtime/fieldobject.cs index 0250cffc4..af772afe2 100644 --- a/src/runtime/fieldobject.cs +++ b/src/runtime/fieldobject.cs @@ -14,7 +14,7 @@ internal class FieldObject : ExtensionType public FieldObject(FieldInfo info) { - this.info = info; + this.info = new MaybeFieldInfo(info); } /// diff --git a/src/runtime/genericutil.cs b/src/runtime/genericutil.cs index 92b847e98..74db54af1 100644 --- a/src/runtime/genericutil.cs +++ b/src/runtime/genericutil.cs @@ -14,7 +14,7 @@ internal static class GenericUtil /// /// Maps namespace -> generic base name -> list of generic type names /// - private static Dictionary>> mapping; + private static Dictionary>> mapping = new(); public static void Reset() { @@ -51,7 +51,7 @@ internal static void Register(Type t) /// /// xxx /// - public static List GetGenericBaseNames(string ns) + public static List? GetGenericBaseNames(string ns) { Dictionary> nsmap; if (!mapping.TryGetValue(ns, out nsmap)) @@ -69,7 +69,7 @@ public static List GetGenericBaseNames(string ns) /// /// Finds a generic type with the given number of generic parameters and the same name and namespace as . /// - public static Type GenericForType(Type t, int paramCount) + public static Type? GenericForType(Type t, int paramCount) { return GenericByName(t.Namespace, t.Name, paramCount); } @@ -77,7 +77,7 @@ public static Type GenericForType(Type t, int paramCount) /// /// Finds a generic type in the given namespace with the given name and number of generic parameters. /// - public static Type GenericByName(string ns, string basename, int paramCount) + public static Type? GenericByName(string ns, string basename, int paramCount) { Dictionary> nsmap; if (!mapping.TryGetValue(ns, out nsmap)) @@ -107,7 +107,7 @@ public static Type GenericByName(string ns, string basename, int paramCount) /// /// xxx /// - public static string GenericNameForBaseName(string ns, string name) + public static string? GenericNameForBaseName(string ns, string name) { Dictionary> nsmap; if (!mapping.TryGetValue(ns, out nsmap)) diff --git a/src/runtime/intern_.cs b/src/runtime/intern_.cs index 09986593e..4884a81ad 100644 --- a/src/runtime/intern_.cs +++ b/src/runtime/intern_.cs @@ -3,7 +3,8 @@ namespace Python.Runtime { static class PyIdentifier - { + { +#pragma warning disable CS0649 // indentifier is never assigned to (assigned with reflection) static IntPtr f__name__; public static BorrowedReference __name__ => new(f__name__); static IntPtr f__dict__; @@ -37,7 +38,8 @@ static class PyIdentifier static IntPtr f__overloads__; public static BorrowedReference __overloads__ => new(f__overloads__); static IntPtr fOverloads; - public static BorrowedReference Overloads => new(fOverloads); + public static BorrowedReference Overloads => new(fOverloads); +#pragma warning restore CS0649 // indentifier is never assigned to (assigned with reflection) } diff --git a/src/runtime/intern_.tt b/src/runtime/intern_.tt index bb8d9f12d..03a26cb50 100644 --- a/src/runtime/intern_.tt +++ b/src/runtime/intern_.tt @@ -30,7 +30,8 @@ using System; namespace Python.Runtime { static class PyIdentifier - { + { +#pragma warning disable CS0649 // indentifier is never assigned to (assigned with reflection) <# foreach (var name in internNames) { @@ -39,7 +40,8 @@ namespace Python.Runtime public static BorrowedReference <#= name #> => new(f<#= name #>); <# } -#> +#> +#pragma warning restore CS0649 // indentifier is never assigned to (assigned with reflection) } diff --git a/src/runtime/interop.cs b/src/runtime/interop.cs index e894fa591..adaac1b6e 100644 --- a/src/runtime/interop.cs +++ b/src/runtime/interop.cs @@ -22,13 +22,7 @@ public DocStringAttribute(string docStr) DocString = docStr; } - public string DocString - { - get { return docStr; } - set { docStr = value; } - } - - private string docStr; + public string DocString { get; } } [Serializable] @@ -204,15 +198,10 @@ internal class ThunkInfo public readonly Delegate Target; public readonly IntPtr Address; - public static readonly ThunkInfo Empty = new ThunkInfo(null); - public ThunkInfo(Delegate target) { - if (target == null) - { - return; - } - Target = target; + Debug.Assert(target is not null); + Target = target!; Address = Marshal.GetFunctionPointerForDelegate(target); } } diff --git a/src/runtime/managedtype.cs b/src/runtime/managedtype.cs index d7472cc61..91ed43473 100644 --- a/src/runtime/managedtype.cs +++ b/src/runtime/managedtype.cs @@ -114,13 +114,14 @@ internal void Save(BorrowedReference ob, InterDomainContext context) OnSave(ob, context); } - internal void Load(BorrowedReference ob, InterDomainContext context) +#warning context appears to be unused + internal void Load(BorrowedReference ob, InterDomainContext? context) { OnLoad(ob, context); } protected virtual void OnSave(BorrowedReference ob, InterDomainContext context) { } - protected virtual void OnLoad(BorrowedReference ob, InterDomainContext context) { } + protected virtual void OnLoad(BorrowedReference ob, InterDomainContext? context) { } protected static void ClearObjectDict(BorrowedReference ob) { diff --git a/src/runtime/methodbinder.cs b/src/runtime/methodbinder.cs index 34462f7c9..0569afe3e 100644 --- a/src/runtime/methodbinder.cs +++ b/src/runtime/methodbinder.cs @@ -3,6 +3,7 @@ using System.Reflection; using System.Text; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; namespace Python.Runtime @@ -23,7 +24,7 @@ internal class MethodBinder public List list; [NonSerialized] - public MethodBase[] methods; + public MethodBase[]? methods; [NonSerialized] public bool init = false; @@ -188,7 +189,7 @@ internal MethodBase[] GetMethods() methods = (from method in list where method.Valid select method.Value).ToArray(); init = true; } - return methods; + return methods!; } /// @@ -376,7 +377,7 @@ public MismatchedMethod(Exception exception, MethodBase mb) { var keyStr = Runtime.GetManagedString(Runtime.PyList_GetItem(keylist.Borrow(), i)); BorrowedReference value = Runtime.PyList_GetItem(valueList.Borrow(), i); - kwargDict[keyStr] = new PyObject(value); + kwargDict[keyStr!] = new PyObject(value); } } diff --git a/src/runtime/methodbinding.cs b/src/runtime/methodbinding.cs index b2d23ab01..8dcd985d0 100644 --- a/src/runtime/methodbinding.cs +++ b/src/runtime/methodbinding.cs @@ -78,12 +78,13 @@ PyObject Signature { ParameterInfo[] altParamters = info.GetParameters(); return i < altParamters.Length ? altParamters[i] : null; - }).Where(p => p != null); + }).WhereNotNull(); using var defaultValue = alternatives - .Select(alternative => alternative.DefaultValue != DBNull.Value ? alternative.DefaultValue.ToPython() : null) - .FirstOrDefault(v => v != null) ?? parameterClass.GetAttr("empty"); + .Select(alternative => alternative!.DefaultValue != DBNull.Value ? alternative.DefaultValue.ToPython() : null) + .FirstOrDefault(v => v != null) ?? parameterClass?.GetAttr("empty"); - if (alternatives.Any(alternative => alternative.Name != parameter.Name)) + if (alternatives.Any(alternative => alternative.Name != parameter.Name) + || positionalOrKeyword is null) { return signatureClass.Invoke(); } @@ -94,7 +95,7 @@ PyObject Signature { kw["default"] = defaultValue; } - using var parameterInfo = parameterClass.Invoke(args: args, kw: kw); + using var parameterInfo = parameterClass!.Invoke(args: args, kw: kw); parameters.Append(parameterInfo); } @@ -209,12 +210,12 @@ public static NewReference tp_call(BorrowedReference ob, BorrowedReference args, // (eg if calling the base class method) then call the original base class method instead // of the target method. IntPtr superType = IntPtr.Zero; - if (target is not null && Runtime.PyObject_TYPE(target) != self.targetType) + if (target is not null && Runtime.PyObject_TYPE(target) != self.targetType!) { var inst = GetManagedObject(target) as CLRObject; if (inst?.inst is IPythonDerivedType) { - var baseType = GetManagedObject(self.targetType) as ClassBase; + var baseType = GetManagedObject(self.targetType!) as ClassBase; if (baseType != null && baseType.type.Valid) { string baseMethodName = "_" + baseType.type.Value.Name + "__" + self.m.name; diff --git a/src/runtime/module.cs b/src/runtime/module.cs index 159fc6912..ada24c6cd 100644 --- a/src/runtime/module.cs +++ b/src/runtime/module.cs @@ -165,6 +165,9 @@ public void Import(PyObject module, string? asname = null) if (module is null) throw new ArgumentNullException(nameof(module)); asname ??= module.GetAttr("__name__").As(); + + if (asname is null) throw new ArgumentException("Module has no name"); + Set(asname, module); } @@ -238,7 +241,7 @@ public PyObject Execute(PyObject script, PyDict? locals = null) /// and convert the result to a Managed Object of given type. /// The ast can be either an expression or stmts. /// - public T Execute(PyObject script, PyDict? locals = null) + public T? Execute(PyObject script, PyDict? locals = null) { Check(); PyObject pyObj = Execute(script, locals); @@ -307,7 +310,7 @@ private void Exec(string code, BorrowedReference _globals, BorrowedReference _lo /// Add a new variable to the variables dict if it not exist /// or update its value if the variable exists. /// - public PyModule Set(string name, object value) + public PyModule Set(string name, object? value) { if (name is null) throw new ArgumentNullException(nameof(name)); @@ -425,7 +428,7 @@ public T Get(string name) Check(); PyObject pyObj = Get(name); - return pyObj.As(); + return pyObj.As()!; } /// @@ -449,13 +452,13 @@ public bool TryGet(string name, out T? value) return true; } - public override bool TryGetMember(GetMemberBinder binder, out object result) + public override bool TryGetMember(GetMemberBinder binder, out object? result) { result = CheckNone(this.Get(binder.Name)); return true; } - public override bool TrySetMember(SetMemberBinder binder, object value) + public override bool TrySetMember(SetMemberBinder binder, object? value) { this.Set(binder.Name, value); return true; diff --git a/src/runtime/moduleobject.cs b/src/runtime/moduleobject.cs index 21435264a..68acaf022 100644 --- a/src/runtime/moduleobject.cs +++ b/src/runtime/moduleobject.cs @@ -23,7 +23,7 @@ internal class ModuleObject : ExtensionType // Attributes to be set on the module according to PEP302 and 451 // by the import machinery. - static readonly HashSet settableAttributes = + static readonly HashSet settableAttributes = new () {"__spec__", "__file__", "__name__", "__path__", "__loader__", "__package__"}; #pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. @@ -142,7 +142,7 @@ public NewReference GetAttribute(string name, bool guess) // enough to complicate the implementation for now. if (guess) { - string gname = GenericUtil.GenericNameForBaseName(this._namespace, name); + string? gname = GenericUtil.GenericNameForBaseName(this._namespace, name); if (gname != null) { var o = this.GetAttribute(gname, false); @@ -343,7 +343,7 @@ public static int tp_traverse(BorrowedReference ob, IntPtr visit, IntPtr arg) public new static int tp_setattro(BorrowedReference ob, BorrowedReference key, BorrowedReference val) { var managedKey = Runtime.GetManagedString(key); - if ((settableAttributes.Contains(managedKey)) || + if ((settableAttributes.Contains(managedKey)) || (ManagedType.GetManagedObject(val) is ModuleObject) ) { var self = (ModuleObject)ManagedType.GetManagedObject(ob)!; @@ -376,7 +376,7 @@ protected override void OnSave(BorrowedReference ob, InterDomainContext context) cache.Clear(); } - protected override void OnLoad(BorrowedReference ob, InterDomainContext context) + protected override void OnLoad(BorrowedReference ob, InterDomainContext? context) { base.OnLoad(ob, context); SetObjectDict(ob, new NewReference(dict).Steal()); diff --git a/src/runtime/native/TypeOffset.cs b/src/runtime/native/TypeOffset.cs index c880db842..3f97b0f45 100644 --- a/src/runtime/native/TypeOffset.cs +++ b/src/runtime/native/TypeOffset.cs @@ -99,7 +99,9 @@ internal static void Use(ITypeOffsets offsets, int extraHeadOffset) static readonly BindingFlags FieldFlags = BindingFlags.NonPublic | BindingFlags.Static; +#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Initialized in ABI.cs static Dictionary SlotOffsets; +#pragma warning restore CS8618 internal static Dictionary GetOffsets() { var properties = typeof(TypeOffset).GetProperties(FieldFlags); diff --git a/src/runtime/operatormethod.cs b/src/runtime/operatormethod.cs index a807f59f3..aad3f013f 100644 --- a/src/runtime/operatormethod.cs +++ b/src/runtime/operatormethod.cs @@ -27,7 +27,7 @@ public SlotDefinition(string methodName, int typeOffset) public int TypeOffset { get; } } - private static PyObject _opType; + private static PyObject? _opType; static OperatorMethod() { @@ -115,7 +115,7 @@ public static void FixupSlots(BorrowedReference pyType, Type clrType) int offset = OpMethodMap[method.Name].TypeOffset; // Copy the default implementation of e.g. the nb_add slot, // which simply calls __add__ on the type. - IntPtr func = Util.ReadIntPtr(_opType, offset); + IntPtr func = Util.ReadIntPtr(_opType!, offset); // Write the slot definition of the target Python type, so // that we can later modify __add___ and it will be called // when used with a Python operator. diff --git a/src/runtime/platform/LibDL.cs b/src/runtime/platform/LibDL.cs index 3bf2a2057..3dad73735 100644 --- a/src/runtime/platform/LibDL.cs +++ b/src/runtime/platform/LibDL.cs @@ -6,7 +6,7 @@ namespace Python.Runtime.Platform { interface ILibDL { - IntPtr dlopen(string fileName, int flags); + IntPtr dlopen(string? fileName, int flags); IntPtr dlsym(IntPtr handle, string symbol); int dlclose(IntPtr handle); IntPtr dlerror(); @@ -38,13 +38,13 @@ public static ILibDL GetInstance() } } - IntPtr ILibDL.dlopen(string fileName, int flags) => dlopen(fileName, flags); + IntPtr ILibDL.dlopen(string? fileName, int flags) => dlopen(fileName, flags); IntPtr ILibDL.dlsym(IntPtr handle, string symbol) => dlsym(handle, symbol); int ILibDL.dlclose(IntPtr handle) => dlclose(handle); IntPtr ILibDL.dlerror() => dlerror(); [DllImport(NativeDll, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] - private static extern IntPtr dlopen(string fileName, int flags); + private static extern IntPtr dlopen(string? fileName, int flags); [DllImport(NativeDll, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] private static extern IntPtr dlsym(IntPtr handle, string symbol); @@ -64,13 +64,13 @@ class LinuxLibDL2 : ILibDL public int RTLD_GLOBAL => 0x100; public IntPtr RTLD_DEFAULT => IntPtr.Zero; - IntPtr ILibDL.dlopen(string fileName, int flags) => dlopen(fileName, flags); + IntPtr ILibDL.dlopen(string? fileName, int flags) => dlopen(fileName, flags); IntPtr ILibDL.dlsym(IntPtr handle, string symbol) => dlsym(handle, symbol); int ILibDL.dlclose(IntPtr handle) => dlclose(handle); IntPtr ILibDL.dlerror() => dlerror(); [DllImport(NativeDll, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] - private static extern IntPtr dlopen(string fileName, int flags); + private static extern IntPtr dlopen(string? fileName, int flags); [DllImport(NativeDll, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] private static extern IntPtr dlsym(IntPtr handle, string symbol); @@ -89,13 +89,13 @@ class MacLibDL : ILibDL const string NativeDll = "/usr/lib/libSystem.dylib"; public IntPtr RTLD_DEFAULT => new(-2); - IntPtr ILibDL.dlopen(string fileName, int flags) => dlopen(fileName, flags); + IntPtr ILibDL.dlopen(string? fileName, int flags) => dlopen(fileName, flags); IntPtr ILibDL.dlsym(IntPtr handle, string symbol) => dlsym(handle, symbol); int ILibDL.dlclose(IntPtr handle) => dlclose(handle); IntPtr ILibDL.dlerror() => dlerror(); [DllImport(NativeDll, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] - private static extern IntPtr dlopen(string fileName, int flags); + private static extern IntPtr dlopen(string? fileName, int flags); [DllImport(NativeDll, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] private static extern IntPtr dlsym(IntPtr handle, string symbol); diff --git a/src/runtime/platform/LibraryLoader.cs b/src/runtime/platform/LibraryLoader.cs index 4148f2391..6d67bea61 100644 --- a/src/runtime/platform/LibraryLoader.cs +++ b/src/runtime/platform/LibraryLoader.cs @@ -8,7 +8,7 @@ namespace Python.Runtime.Platform { interface ILibraryLoader { - IntPtr Load(string dllToLoad); + IntPtr Load(string? dllToLoad); IntPtr GetFunction(IntPtr hModule, string procedureName); @@ -17,7 +17,7 @@ interface ILibraryLoader static class LibraryLoader { - static ILibraryLoader _instance = null; + static ILibraryLoader? _instance = null; public static ILibraryLoader Instance { @@ -51,7 +51,7 @@ public PosixLoader(ILibDL libDL) this.libDL = libDL ?? throw new ArgumentNullException(nameof(libDL)); } - public IntPtr Load(string dllToLoad) + public IntPtr Load(string? dllToLoad) { ClearError(); var res = libDL.dlopen(dllToLoad, libDL.RTLD_NOW | libDL.RTLD_GLOBAL); @@ -107,8 +107,9 @@ class WindowsLoader : ILibraryLoader private const string NativeDll = "kernel32.dll"; - public IntPtr Load(string dllToLoad) + public IntPtr Load(string? dllToLoad) { + if (dllToLoad is null) return IntPtr.Zero; var res = WindowsLoader.LoadLibrary(dllToLoad); if (res == IntPtr.Zero) throw new DllNotFoundException($"Could not load {dllToLoad}.", new Win32Exception()); diff --git a/src/runtime/propertyobject.cs b/src/runtime/propertyobject.cs index f9ae2585d..140bd47b5 100644 --- a/src/runtime/propertyobject.cs +++ b/src/runtime/propertyobject.cs @@ -18,7 +18,7 @@ public PropertyObject(PropertyInfo md) { getter = md.GetGetMethod(true); setter = md.GetSetMethod(true); - info = md; + info = new MaybeMemberInfo(md); } diff --git a/src/runtime/pyobject.cs b/src/runtime/pyobject.cs index 894fff329..709bc11c4 100644 --- a/src/runtime/pyobject.cs +++ b/src/runtime/pyobject.cs @@ -175,7 +175,7 @@ public static PyObject FromManagedObject(object ob) /// Return a managed object of the given type, based on the /// value of the Python object. /// - public T As() => (T)this.AsManagedObject(typeof(T)); + public T As() => (T)this.AsManagedObject(typeof(T))!; internal bool IsDisposed => rawPtr == IntPtr.Zero; diff --git a/src/runtime/runtime_data.cs b/src/runtime/runtime_data.cs index 4d49255e2..f30a54dbe 100644 --- a/src/runtime/runtime_data.cs +++ b/src/runtime/runtime_data.cs @@ -17,8 +17,8 @@ namespace Python.Runtime { public static class RuntimeData { - private static Type _formatterType; - public static Type FormatterType + private static Type? _formatterType; + public static Type? FormatterType { get => _formatterType; set @@ -31,7 +31,7 @@ public static Type FormatterType } } - public static ICLRObjectStorer WrappersStorer { get; set; } + public static ICLRObjectStorer? WrappersStorer { get; set; } /// /// Clears the old "clr_data" entry if a previous one is present. @@ -57,7 +57,7 @@ internal static void Stash() Classes = ClassManager.SaveRuntimeData(), SharedObjects = SaveRuntimeDataObjects(), }; - + IFormatter formatter = CreateFormatter(); var ms = new MemoryStream(); formatter.Serialize(ms, runtimeStorage); @@ -171,9 +171,8 @@ private static SharedObjectsState SaveRuntimeDataObjects() // Wrapper must be the CLRObject var clrObj = (CLRObject)ManagedType.GetManagedObject(pyObj)!; object inst = clrObj.inst; - CLRMappedItem item; List mappedObjs; - if (!userObjects.TryGetValue(inst, out item)) + if (!userObjects.TryGetValue(inst, out var item)) { item = new CLRMappedItem(inst); userObjects.Add(item); @@ -260,63 +259,28 @@ private static IFormatter CreateFormatter() [Serializable] public class RuntimeDataStorage { - private Stack _stack; - private Dictionary _namedValues; + private Dictionary? _namedValues; public T AddValue(string name, T value) { if (_namedValues == null) { - _namedValues = new Dictionary(); + _namedValues = new Dictionary(); } _namedValues.Add(name, value); return value; } - public object GetValue(string name) - { - return _namedValues[name]; - } - - public T GetValue(string name) - { - return (T)GetValue(name); - } - - public T GetValue(string name, out T value) - { - value = GetValue(name); - return value; - } - - public RuntimeDataStorage GetStorage(string name) - { - return GetValue(name); - } - - public T PushValue(T value) - { - if (_stack == null) - { - _stack = new Stack(); - } - _stack.Push(value); - return value; - } - - public object PopValue() - { - return _stack.Pop(); - } - - public T PopValue() + public object? GetValue(string name) { - return (T)PopValue(); + return _namedValues is null + ? throw new KeyNotFoundException() + : _namedValues[name]; } - public T PopValue(out T value) + public T? GetValue(string name) { - return value = (T)PopValue(); + return (T?)GetValue(name); } } @@ -324,7 +288,7 @@ public T PopValue(out T value) [Serializable] class InterDomainContext { - private RuntimeDataStorage _storage; + private RuntimeDataStorage? _storage; public RuntimeDataStorage Storage => _storage ?? (_storage = new RuntimeDataStorage()); } } diff --git a/src/runtime/tricks/InitOnly.cs b/src/runtime/tricks/InitOnly.cs new file mode 100644 index 000000000..5ead4123a --- /dev/null +++ b/src/runtime/tricks/InitOnly.cs @@ -0,0 +1,4 @@ +namespace System.Runtime.CompilerServices +{ + internal static class IsExternalInit { } +} diff --git a/src/runtime/typemanager.cs b/src/runtime/typemanager.cs index 834703e80..c0a835943 100644 --- a/src/runtime/typemanager.cs +++ b/src/runtime/typemanager.cs @@ -19,7 +19,11 @@ internal class TypeManager { internal static IntPtr subtype_traverse; internal static IntPtr subtype_clear; +#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. + /// initialized in rather than in constructor internal static IPythonBaseTypeProvider pythonBaseTypeProvider; +#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. + private const BindingFlags tbFlags = BindingFlags.Public | BindingFlags.Static; private static Dictionary cache = new(); @@ -78,7 +82,7 @@ internal static void RestoreRuntimeData(TypeManagerState storage) foreach (var entry in typeCache) { Type type = entry.Key.Value;; - cache[type] = entry.Value; + cache![type] = entry.Value; SlotsHolder holder = CreateSlotsHolder(entry.Value); InitializeSlots(entry.Value, type, holder); Runtime.PyType_Modified(entry.Value); @@ -624,7 +628,7 @@ static void InheritSubstructs(IntPtr type) /// provides the implementation for the type, connect the type slots of /// the Python object to the managed methods of the implementing Type. /// - internal static void InitializeSlots(PyType type, Type impl, SlotsHolder slotsHolder = null) + internal static void InitializeSlots(PyType type, Type impl, SlotsHolder? slotsHolder = null) { // We work from the most-derived class up; make sure to get // the most-derived slot and not to override it with a base @@ -654,7 +658,7 @@ internal static void InitializeSlots(PyType type, Type impl, SlotsHolder slotsHo } var initSlot = impl.GetMethod("InitializeSlots", BindingFlags.Static | BindingFlags.Public); - initSlot?.Invoke(null, parameters: new object[] { type, seen, slotsHolder }); + initSlot?.Invoke(null, parameters: new object?[] { type, seen, slotsHolder }); impl = impl.BaseType; } @@ -675,7 +679,7 @@ private static void SetRequiredSlots(PyType type, HashSet seen) } } - static void InitializeSlot(BorrowedReference type, ThunkInfo thunk, string name, SlotsHolder slotsHolder) + static void InitializeSlot(BorrowedReference type, ThunkInfo thunk, string name, SlotsHolder? slotsHolder) { if (!Enum.TryParse(name, out var id)) { @@ -703,7 +707,7 @@ internal static void InitializeSlotIfEmpty(BorrowedReference type, int slotOffse InitializeSlot(type, slotOffset, impl, slotsHolder); } - static void InitializeSlot(BorrowedReference type, int slotOffset, ThunkInfo thunk, SlotsHolder slotsHolder) + static void InitializeSlot(BorrowedReference type, int slotOffset, ThunkInfo thunk, SlotsHolder? slotsHolder) { Util.WriteIntPtr(type, slotOffset, thunk.Address); if (slotsHolder != null)