private static readonly Field[] _emptyFields = new Field[0]; // fields were never initialized before a type was created public StructType(CodeContext /*!*/ context, string name, PythonTuple bases, PythonDictionary members) : base(context, name, bases, members) { foreach (PythonType pt in ResolutionOrder) { StructType st = pt as StructType; if (st != this) { st?.EnsureFinal(); } if (pt is UnionType ut) { ut.EnsureFinal(); } } if (members.TryGetValue("_pack_", out object pack)) { if (!(pack is int) || ((int)pack < 0)) { throw PythonOps.ValueError("pack must be a non-negative integer"); } _pack = (int)pack; } if (members.TryGetValue("_fields_", out object fields)) { __setattr__(context, "_fields_", fields); } // TODO: _anonymous_ }
/// <summary> /// Shared helper between struct and union for getting field info and validating it. /// </summary> private static void GetFieldInfo(INativeType type, object o, out string fieldName, out INativeType cdata, out int?bitCount) { PythonTuple pt = o as PythonTuple; if (pt.Count != 2 && pt.Count != 3) { throw PythonOps.AttributeError("'_fields_' must be a sequence of pairs"); } fieldName = pt[0] as string; if (fieldName == null) { throw PythonOps.TypeError("first item in _fields_ tuple must be a string, got", PythonTypeOps.GetName(pt[0])); } cdata = pt[1] as INativeType; if (cdata == null) { throw PythonOps.TypeError("second item in _fields_ tuple must be a C type, got {0}", PythonTypeOps.GetName(pt[0])); } else if (cdata == type) { throw StructureCannotContainSelf(); } StructType st = cdata as StructType; if (st != null) { st.EnsureFinal(); } if (pt.Count != 3) { bitCount = null; } else { bitCount = CheckBits(cdata, pt); } }
private static readonly Field[] _emptyFields = new Field[0]; // fields were never initialized before a type was created public StructType(CodeContext /*!*/ context, string name, PythonTuple bases, PythonDictionary members) : base(context, name, bases, members) { foreach (PythonType pt in ResolutionOrder) { StructType st = pt as StructType; if (st != this && st != null) { st.EnsureFinal(); } UnionType ut = pt as UnionType; if (ut != null) { ut.EnsureFinal(); } } object pack; if (members.TryGetValue("_pack_", out pack)) { if (!(pack is int) || ((int)pack < 0)) { throw PythonOps.ValueError("pack must be a non-negative integer"); } _pack = (int)pack; } object fields; if (members.TryGetValue("_fields_", out fields)) { // When we support alternate endianness this should change to: //__setattr__(context, "_fields_", fields); SetFields(fields); } // TODO: _anonymous_ }
private static readonly Field[] _emptyFields = new Field[0]; // fields were never initialized before a type was created public StructType(CodeContext /*!*/ context, string name, PythonTuple bases, PythonDictionary members) : base(context, name, bases, members) { foreach (PythonType pt in ResolutionOrder) { StructType st = pt as StructType; if (st != this) { st?.EnsureFinal(); } if (pt is UnionType ut) { ut.EnsureFinal(); } } if (members.TryGetValue("_pack_", out object pack)) { object index = PythonOps.Index(pack); // since 3.8 _pack = index switch { int i => i, BigInteger bi => (int)bi, // CPython throws the ValueError below on overflow _ => throw new InvalidOperationException(), }; if (_pack < 0) { throw PythonOps.ValueError("pack must be a non-negative integer"); } } if (members.TryGetValue("_fields_", out object fields)) { __setattr__(context, "_fields_", fields); } // TODO: _anonymous_ }