internal bool TryLookupSlotInBases(ICallerContext context, SymbolId name, out object ret) { Tuple resOrder = MethodResolutionOrder; for (int i = 1; i < resOrder.Count; i++) // skip our own type... { object type = resOrder[i]; PythonType pt = type as PythonType; if (pt != null) { if (pt.TryGetSlot(context, name, out ret)) { // respect MRO for base class lookups: method wrappers are // logically a member of a super type, but are available on // derived types for quick access. We only want to return a method // wrapper here if it's actually exposed on our type. MethodWrapper mw = ret as MethodWrapper; if (mw == null || !mw.IsSuperTypeMethod()) { return(true); } } } else if (Ops.TryGetAttr(context, type, name, out ret)) { return(true); } } ret = null; return(false); }
public List GetAttrNames(ICallerContext context) { FieldIdDict attrs = new FieldIdDict(__dict__); OldClass.RecurseAttrHierarchy(this.__class__, attrs); return(List.Make(attrs)); }
public static Tuple OpenPipedCommandAll(ICallerContext context, string command, string mode, int bufsize) { if (String.IsNullOrEmpty(mode)) { mode = "t"; } if (mode != "t" && mode != "b") { throw Ops.ValueError("mode must be 't' or 'b' (default is t)"); } if (mode == "t") { mode = String.Empty; } ProcessStartInfo psi = GetProcessInfo(command); psi.RedirectStandardInput = true; psi.RedirectStandardOutput = true; psi.RedirectStandardError = true; Process p = Process.Start(psi); return(Tuple.MakeTuple(new POpenFile(context, command, p, p.StandardInput.BaseStream, "w" + mode), new POpenFile(context, command, p, p.StandardOutput.BaseStream, "r" + mode), new POpenFile(context, command, p, p.StandardError.BaseStream, "r+" + mode))); }
public static PythonFile OpenPipedCommand(ICallerContext context, string command, string mode, int bufsize) { if (String.IsNullOrEmpty(mode)) { mode = "r"; } ProcessStartInfo psi = GetProcessInfo(command); Process p; PythonFile res; switch (mode) { case "r": psi.RedirectStandardOutput = true; p = Process.Start(psi); res = new POpenFile(context, command, p, p.StandardOutput.BaseStream, "r"); break; case "w": psi.RedirectStandardInput = true; p = Process.Start(psi); res = new POpenFile(context, command, p, p.StandardInput.BaseStream, "w"); break; default: throw Ops.ValueError("expected 'r' or 'w' for mode, got {0}", mode); } return(res); }
public List GetAttrNames(ICallerContext context) { List ret = new List(((IDictionary <object, object>)__dict__).Keys); ret.Extend(TypeCache.SystemState.GetAttrNames(context, this)); return(ret); }
public static object Open(ICallerContext context, string filename, int flag, int mode) { FileStream fs = File.Open(filename, FileModeFromFlags(flag), FileAccessFromFlags(flag)); PythonFile pf = PythonFile.Make(context, null, fs); return(PythonFileManager.GetIdFromFile(pf)); }
public virtual bool TryGetAttr(ICallerContext context, SymbolId name, out object value) { switch (name.Id) { case SymbolTable.NameId: value = __name__; return(true); case SymbolTable.BasesId: value = BaseClasses; return(true); case SymbolTable.ClassId: value = Ops.GetDynamicType(this); return(true); case SymbolTable.SubclassesId: ReflectedMethod rm = new ReflectedMethod("__subclasses__", typeof(ReflectedType).GetMethod("__subclasses__"), FunctionType.PythonVisible | FunctionType.Method);; rm.inst = this; value = rm; return(true); default: if (TryLookupSlot(context, name, out value)) { value = Ops.GetDescriptor(value, null, this); return(true); } break; } return(false); }
/// <summary> /// Gateway into importing ... called from Ops. This is called after /// importing the module and is used to return individual items from /// the module. The outer modules dictionary is then updated with the /// result. /// </summary> internal static object ImportFrom(ICallerContext context, object mod, string name) { PythonModule from = mod as PythonModule; if (from != null) { object ret; if (from.TryGetAttr(from, SymbolTable.StringToId(name), out ret)) { return(ret); } else { return(ImportNested(from, name)); } } else { object ret; if (Ops.TryGetAttr(context, mod, SymbolTable.StringToId(name), out ret)) { return(ret); } else { throw Ops.ImportError("No module named {0}", name); } } }
public int GetExitCode(ICallerContext context) { object pyObj = ExceptionConverter.ToPython(this); object args; if (!Ops.TryGetAttr(pyObj, SymbolTable.Arguments, out args)) { return(0); } Tuple t = args as Tuple; if (t == null || t.Count == 0) { return(0); } try { return(Converter.ConvertToInt32(t[0])); } catch { } try { Ops.PrintWithDest(context.SystemState, context.SystemState.stderr, t[0]); } catch { } return(1); }
public bool TryGetAttr(ICallerContext context, SymbolId name, out object value) { if (name.Id == SymbolTable.DictId) { //!!! user code can modify __del__ property of __dict__ behind our back value = __dict__; return(true); } else if (name.Id == SymbolTable.Class.Id) { value = __class__; return(true); } if (TryRawGetAttr(name, out value)) { return(true); } if (name.Id != SymbolTable.GetAttrId) { object getattr; if (TryRawGetAttr(SymbolTable.GetAttr, out getattr)) { value = Ops.Call(getattr, SymbolTable.IdToString(name)); return(true); } } return(false); }
object ICallableWithCallerContext.Call(ICallerContext context, object[] args) { object newMethod, newObject; newMethod = Ops.GetAttr(context, this, SymbolTable.NewInst); newObject = Ops.CallWithContext(context, newMethod, PrependThis(args)); if (newObject == null) { return(null); } if (Ops.GetDynamicType(newObject).IsSubclassOf(this)) { object init; if (PythonType.TryLookupSpecialMethod(DefaultContext.Default, newObject, SymbolTable.Init, out init)) { switch (args.Length) { case 0: Ops.CallWithContext(context, init); break; case 1: Ops.CallWithContext(context, init, args[0]); break; case 2: Ops.CallWithContext(context, init, args[0], args[1]); break; default: Ops.CallWithContext(context, init, args); break; } } } return(newObject); }
public List GetAttrNames(ICallerContext context) { List list; if (dict == null) { list = List.Make(); } else { list = List.Make(dict); } list.AddNoLock(SymbolTable.Module.ToString()); List reflectedAttrs = GetDynamicType().GetAttrNames(context, this); foreach (object o in reflectedAttrs) { if (list.Contains(o)) { continue; } list.AddNoLock(o); } return(list); }
public override void SetAttr(ICallerContext context, object self, SymbolId name, object value) { if (name == SymbolTable.Class) { // check that this is a legal new class UserType newType = value as UserType; if (newType == null) { throw Ops.TypeError("__class__ must be set to new-style class, not '{0}' object", Ops.GetDynamicType(value).__name__); } if (newType.type != this.type) { throw Ops.TypeError("__class__ assignment: '{0}' object layout differs from '{1}'", __name__, newType.__name__); } ((ISuperDynamicObject)self).SetDynamicType(newType); return; } if (__setattr__F.IsObjectMethod()) { BaseSetAttr(context, (ISuperDynamicObject)self, name, value); } else { __setattr__F.Invoke(self, SymbolTable.IdToString(name), value); } }
public void SetAttr(ICallerContext context, SymbolId name, object value) { switch (name.Id) { case SymbolTable.BasesId: __bases__ = ValidateBases(value); break; case SymbolTable.NameId: string n = value as string; if (n == null) { throw Ops.TypeError("TypeError: __name__ must be a string object"); } __name__ = n; break; case SymbolTable.DictId: IAttributesDictionary d = value as IAttributesDictionary; if (d == null) { throw Ops.TypeError("__dict__ must be set to dictionary"); } __dict__ = d; break; case SymbolTable.UnassignId: hasFinalizer = true; goto default; default: __dict__[name] = value; break; } }
public static List Dir(ICallerContext context, object o) { List ret = Ops.GetAttrNames(context, o); ret.Sort(); return(ret); }
public void DeleteAttr(ICallerContext context, SymbolId name) { switch (name.Id) { case SymbolTable.ClassId: throw Ops.TypeError("__class__ must be set to class"); case SymbolTable.DictId: throw Ops.TypeError("__dict__ must be set to a dictionary"); default: if (name == SymbolTable.Unassign) { // removing finalizer if (HasFinalizer() && !__class__.HasFinalizer) { ClearFinalizer(); } } if (!__dict__.Remove(name)) { throw Ops.AttributeError("{0} is not a valid attribute", SymbolTable.IdToString(name)); } break; } }
public void DeleteAttr(ICallerContext context, SymbolId name) { if (!GetTypeMap().Remove(name)) { throw Ops.AttributeError("namespace {0} has no type/nested namespace {1}", myNamespace, name); } }
private void Initialize(ICallerContext context) { int prevVal = Interlocked.CompareExchange(ref initialized, 1, 0); if (prevVal == 2) { return; // fully initialized, leave... } if (prevVal != 0) { while (Thread.VolatileRead(ref initialized) != 2) { Thread.SpinWait(10000); } return; } try { AddInterfaces(context); Interlocked.Exchange(ref initialized, 2); } catch { // initialization failed. Interlocked.Exchange(ref initialized, 0); throw; } }
private static Type GetInterfaceForGuid(ICallerContext context, Guid typeInfoGuid, IntPtr typeInfoPtr) { Type interfaceType; if (ComTypeCache.TryGetValue(typeInfoGuid, out interfaceType) == false) { Assembly interopAssembly = SearchForInteropAssembly(typeInfoGuid); if (interopAssembly != null) { context.SystemState.TopPackage.LoadAssembly(context.SystemState, interopAssembly, false); ComTypeCache.TryGetValue(typeInfoGuid, out interfaceType); } if (interfaceType == null && typeInfoPtr != IntPtr.Zero) { // This can be very slow. Hence we call SearchForInteropAssembly before we do this. interfaceType = Marshal.GetTypeForITypeInfo(typeInfoPtr); if (interfaceType != null) { ComTypeCache[typeInfoGuid] = interfaceType; } } } return(interfaceType); }
internal List GetAttrNames(ICallerContext context) { Initialize(context); List list = List.Make(); if (HaveInterfaces) { foreach (DynamicType type in interfaces) { List names = type.GetAttrNames(context, obj); foreach (object o in names) { if (!list.Contains(o)) { list.AddNoLock(o); } } } } else { //return GetDynamicType().GetAttrNames(context, this); } return(list); }
public override object Call(ICallerContext context, params object[] args) { switch (args.Length) { case 0: return Call(context); default: throw BadArgumentError(args.Length); } }
public override Dict GetAttrDict(ICallerContext context, object self) { // Get the entries from the type Dict res = new Dict(GetAttrDict(context)); // Add the entries from the instance ISuperDynamicObject sdo = self as ISuperDynamicObject; if (sdo != null) { IAttributesDictionary dict = sdo.GetDict(); if (dict != null) { foreach (KeyValuePair <object, object> val in dict) { object fieldName = val.Key; if (!res.ContainsKey(fieldName)) { res.Add(new KeyValuePair <object, object>(fieldName, val.Value)); } } } } return(res); }
public bool TryGetAttr(ICallerContext context, SymbolId name, out object value) { if (name == SymbolTable.Dict) { value = EnsureDict(); return(true); } if (dict != null) { if (dict.TryGetValue(name, out value)) { return(true); } } // We check for SymbolTable.Module as the user code can modify it if (name == SymbolTable.Module) { value = Module.ModuleName; return(true); } return(GetDynamicType().TryGetAttr(context, this, name, out value)); }
public override bool TryGetAttr(ICallerContext context, object self, SymbolId name, out object ret) { if (__getattribute__F.IsObjectMethod()) { ISuperDynamicObject sdo = self as ISuperDynamicObject; if (sdo != null) { return(TryBaseGetAttr(context, sdo, name, out ret)); } else { ret = null; return(false); } } else { try { ret = __getattribute__F.Invoke(self, SymbolTable.IdToString(name)); return(true); } catch (MissingMemberException) { ret = null; return(false); } } }
public override object Call(ICallerContext context, object arg0, object arg1, object arg2, object arg3, object arg4) { if (HasInstance) { return(target(new object[] { Instance, arg0, arg1, arg2, arg3, arg4 })); } return(target(new object[] { arg0, arg1, arg2, arg3, arg4 })); }
public List GetAttrNames(ICallerContext context) { LoadAllTypes(); List res = new List(((IDictionary<object, object>)__dict__).Keys); res.Sort(); return res; }
public override object Call(ICallerContext context, object arg0, object arg1, object arg2, object arg3, object arg4) { if ((this.FunctionType & FunctionType.Function) == 0 && HasInstance) { throw BadArgumentError(5); } return(target(arg0, arg1, arg2, arg3, arg4)); }
public override object Call(ICallerContext context, object arg0, object arg1, object arg2) { if (!HasInstance || !IsContextAware) { throw BadArgumentError(3); } return(target(context, Instance, arg0, arg1, arg2)); }
public override object Call(ICallerContext context, object arg0) { if (HasInstance) { return(target(new object[] { Instance, arg0 })); } return(target(new object[] { arg0 })); }
public KwArgBinder(ICallerContext context, object[] args, string[] keyNames, bool allowUnboundArgs) { arguments = args; kwNames = keyNames; Debug.Assert(keyNames.Length <= args.Length); fAllowUnboundArgs = allowUnboundArgs; ctx = context; }
public ThreadObj(ICallerContext context, object function, Tuple args, object kwargs) { Debug.Assert(args != null); func = function; this.kwargs = kwargs; this.args = args; this.context = context; }
public static Tuple FindModule(ICallerContext context, string name, List path) { if (path == null) { return FindBuiltinOrSysPath(context, name); } else { return FindModulePath(context, name, path); } }
protected bool TryLookupSlot(ICallerContext context, SymbolId name, out object ret) { if (TryGetSlot(context, name, out ret)) { return(true); } return(TryLookupSlotInBases(context, name, out ret)); }
public IDictionary <object, object> GetAttrDict(ICallerContext context) { if (dict == null) { return(new Dict(0)); } return((IDictionary <object, object>)dict); }
public override object Call(ICallerContext context) { if (!EnforceRecursion) return target(); PushFrame(); try { return target(); } finally { PopFrame(); } }
public override bool TryGetAttr(ICallerContext context, object self, SymbolId name, out object ret) { if (base.TryGetAttr(context, self, name, out ret)) { return true; } // This will force creation of the instances dict IAttributesDictionary dict = ((ISuperDynamicObject)self).GetDict(); return dict.TryGetValue(name, out ret); }
public object Call(ICallerContext context, object[] args, string[] names) { object targetMethod; if (!Ops.GetDynamicType(target).TryLookupBoundSlot(context, target, name, out targetMethod)) throw Ops.AttributeError("type {0} has no attribute {1}", Ops.GetDynamicType(target.Target), name.ToString()); return Ops.Call(context, targetMethod, args, names); }
public override List GetAttrNames(ICallerContext context, object self) { Assembly asm = self as Assembly; TopReflectedPackage reflectedAssembly = GetReflectedAssembly(context.SystemState, asm); List ret = base.GetAttrNames(context, self); ret.AddRange(reflectedAssembly.GetAttrNames(context)); return ret; }
public override Dict GetAttrDict(ICallerContext context, object self) { List attrs = GetAttrNames(context, self); Dict res = new Dict(); foreach (string o in attrs) { res[o] = GetAttr(context, self, SymbolTable.StringToId(o)); } return res; }
public override void SetAttr(ICallerContext context, object self, SymbolId name, object value) { object slot; bool success = TryGetSlot(context, name, out slot); if (success) { success = Ops.SetDescriptor(slot, self, value); } if (!success) { // otherwise update the instance IAttributesDictionary dict = ((ISuperDynamicObject)self).GetDict(); dict[name] = value; } }
public override bool TryGetAttr(ICallerContext context, object self, SymbolId name, out object ret) { Assembly asm = self as Assembly; TopReflectedPackage reflectedAssembly = GetReflectedAssembly(context.SystemState, asm); if (name == SymbolTable.Dict) { ret = reflectedAssembly.GetAttrDict(context); return true; } if (base.TryGetAttr(context, self, name, out ret)) { return true; } if (!reflectedAssembly.TryGetAttr(context, name, out ret)) throw Ops.AttributeError("assembly {0} has no type {1}", asm.GetName().Name, name); return true; }
public static object Reduce(ICallerContext context, object self, object protocol) { object objectReduce = Ops.GetAttr(DefaultContext.Default, Ops.GetDynamicTypeFromType(typeof(object)), SymbolTable.Reduce); object myReduce; if (Ops.TryGetAttr(DefaultContext.Default, Ops.GetDynamicType(self), SymbolTable.Reduce, out myReduce)) { if (!Ops.IsRetBool(myReduce, objectReduce)) { // A derived class overrode __reduce__ but not __reduce_ex__, so call // specialized __reduce__ instead of generic __reduce_ex__. // (see the "The __reduce_ex__ API" section of PEP 307) return Ops.Call(myReduce, self); } } if (Converter.ConvertToInt32(protocol) < 2) { return ReduceProtocol0(context, self); } else { return ReduceProtocol2(context, self); } }
private void SaveLong(ICallerContext context, object obj) { Debug.Assert(Ops.GetDynamicType(obj).Equals(TypeCache.BigInteger), "arg must be long"); if (protocol < 2) { Write(Opcode.Long); WriteLongAsString(obj); } else { if (((BigInteger)obj).IsZero()) { Write(Opcode.Long1); WriteUInt8(0); } else { byte[] dataBytes = ((BigInteger)obj).ToByteArray(); if (dataBytes.Length < 256) { Write(Opcode.Long1); WriteUInt8(dataBytes.Length); } else { Write(Opcode.Long4); WriteInt32(dataBytes.Length); } foreach (byte b in dataBytes) { WriteUInt8(b); } } } }
/// <summary> /// Implements the default __reduce_ex__ method as specified by PEP 307 case 3 (new-style instance, protocol 2) /// </summary> private static Tuple ReduceProtocol2(ICallerContext context, object self) { DynamicType myType = Ops.GetDynamicType(self); object func, state, listIterator, dictIterator; object[] funcArgs; func = PythonCopyReg.PythonNewObject; object getNewArgsCallable; if (Ops.TryGetAttr(myType, SymbolTable.GetNewArgs, out getNewArgsCallable)) { // TypeError will bubble up if __getnewargs__ isn't callable Tuple newArgs = Ops.Call(getNewArgsCallable, self) as Tuple; if (newArgs == null) { throw Ops.TypeError("__getnewargs__ should return a tuple"); } funcArgs = new object[1 + newArgs.Count]; funcArgs[0] = myType; for (int i = 0; i < newArgs.Count; i++) funcArgs[i + 1] = newArgs[i]; } else { funcArgs = new object[] { myType }; } if (!Ops.TryInvokeSpecialMethod(self, SymbolTable.GetState, out state)) { object dict; if (!Ops.TryGetAttr(self, SymbolTable.Dict, out dict)) { dict = null; } Dict initializedSlotValues = GetInitializedSlotValues(self); if (initializedSlotValues != null && initializedSlotValues.Count == 0) { initializedSlotValues = null; } if (dict == null && initializedSlotValues == null) state = null; else if (dict != null && initializedSlotValues == null) state = dict; else if (dict != null && initializedSlotValues != null) state = Tuple.MakeTuple(dict, initializedSlotValues); else /*dict == null && initializedSlotValues != null*/ state = Tuple.MakeTuple(null, initializedSlotValues); } listIterator = null; if (self is List) { listIterator = Ops.GetEnumerator(self); } dictIterator = null; if (self is Dict) { dictIterator = Ops.Invoke(self, SymbolTable.IterItems, Ops.EMPTY); } return Tuple.MakeTuple(func, Tuple.MakeTuple(funcArgs), state, listIterator, dictIterator); }
public static object Reduce(ICallerContext context, object self) { return Reduce(context, self, 0); }
private void SaveDict(ICallerContext context, object obj) { Debug.Assert(Ops.GetDynamicType(obj).Equals(TypeCache.Dict), "arg must be dict"); Debug.Assert(!memo.Contains(Ops.Id(obj))); Memoize(obj); if (protocol < 1) { Write(Opcode.Mark); Write(Opcode.Dict); } else { Write(Opcode.EmptyDict); } WritePut(obj); BatchSetItems(context, (DictOps.IterItems((IDictionary<object, object>)obj))); }
/// <summary> /// Implements the default __reduce_ex__ method as specified by PEP 307 case 2 (new-style instance, protocol 0 or 1) /// </summary> private static Tuple ReduceProtocol0(ICallerContext context, object self) { // CPython implements this in copy_reg._reduce_ex DynamicType myType = Ops.GetDynamicType(self); // PEP 307 calls this "D" ThrowIfNativelyPickable(myType); object getState; bool hasGetState = Ops.TryGetAttr(self, SymbolTable.GetState, out getState); object slots; if (Ops.TryGetAttr(myType, SymbolTable.Slots, out slots) && Ops.Length(slots) > 0 && !hasGetState) { // ??? does this work with superclass slots? throw Ops.TypeError("a class that defines __slots__ without defining __getstate__ cannot be pickled with protocols 0 or 1"); } DynamicType closestNonPythonBase = FindClosestNonPythonBase(myType); // PEP 307 calls this "B" object func = PythonCopyReg.PythonReconstructor; object funcArgs = Tuple.MakeTuple( myType, closestNonPythonBase, TypeCache.Object == closestNonPythonBase ? null : Ops.Call(closestNonPythonBase, self) ); object state; if (hasGetState) { state = Ops.Call(getState); } else { Ops.TryGetAttr(self, SymbolTable.Dict, out state); } if (!Ops.IsTrue(state)) state = null; return Tuple.MakeTuple(func, funcArgs, state); }
private void Save(ICallerContext context, object obj) { if (memo.Contains(Ops.Id(obj))) { WriteGet(obj); } else { PickleFunction pickleFunction; DynamicType objType = Ops.GetDynamicType(obj); if (!dispatchTable.TryGetValue(objType, out pickleFunction)) { if (objType.IsSubclassOf(TypeCache.DynamicType)) { // treat classes with metaclasses like regular classes pickleFunction = SaveGlobal; } else { pickleFunction = SaveObject; } } pickleFunction(context, obj); } }
private void SaveFloat(ICallerContext context, object obj) { Debug.Assert(Ops.GetDynamicType(obj).Equals(TypeCache.Double), "arg must be float"); if (protocol < 1) { Write(Opcode.Float); WriteFloatAsString(obj); } else { Write(Opcode.BinFloat); WriteFloat64(obj); } }
private void SaveGlobal(ICallerContext context, object obj) { Debug.Assert( Ops.GetDynamicType(obj).Equals(TypeCache.OldClass) || Ops.GetDynamicType(obj).Equals(TypeCache.Function) || Ops.GetDynamicType(obj).Equals(TypeCache.BuiltinFunction) || Ops.GetDynamicType(obj).Equals(TypeCache.DynamicType) || Ops.GetDynamicType(obj).IsSubclassOf(TypeCache.DynamicType), "arg must be classic class, function, built-in function or method, or new-style type" ); object name; if (Ops.TryGetAttr(obj, SymbolTable.Name, out name)) { SaveGlobalByName(context, obj, name); } else { throw CannotPickle(obj, "could not determine its __name__"); } }
private void SaveList(ICallerContext context, object obj) { Debug.Assert(Ops.GetDynamicType(obj).Equals(TypeCache.List), "arg must be list"); Debug.Assert(!memo.Contains(Ops.Id(obj))); Memoize(obj); if (protocol < 1) { Write(Opcode.Mark); Write(Opcode.List); } else { Write(Opcode.EmptyList); } WritePut(obj); BatchAppends(context, ((IEnumerable)obj).GetEnumerator()); }
private void SaveInteger(ICallerContext context, object obj) { Debug.Assert(Ops.GetDynamicType(obj).Equals(TypeCache.Int32), "arg must be int"); if (protocol < 1) { Write(Opcode.Int); WriteIntAsString(obj); } else { if (IsUInt8(obj)) { Write(Opcode.BinInt1); WriteUInt8(obj); } else if (IsUInt16(obj)) { Write(Opcode.BinInt2); WriteUInt16(obj); } else if (IsInt32(obj)) { Write(Opcode.BinInt); WriteInt32(obj); } else { throw Ops.RuntimeError("unrecognized integer format"); } } }
private void SaveInstance(ICallerContext context, object obj) { Debug.Assert(Ops.GetDynamicType(obj).Equals(TypeCache.OldInstance), "arg must be old-class instance"); Debug.Assert(!memo.Contains(Ops.Id(obj))); Write(Opcode.Mark); // Memoize() call isn't in the usual spot to allow class to be memoized before // instance (when using proto other than 0) to match CPython's bytecode output object objClass; if (!Ops.TryGetAttr(obj, SymbolTable.Class, out objClass)) { throw CannotPickle(obj, "could not determine its __class__"); } if (protocol < 1) { object className, classModuleName; if (!Ops.TryGetAttr(objClass, SymbolTable.Name, out className)) { throw CannotPickle(obj, "its __class__ has no __name__"); } classModuleName = FindModuleForGlobal(context, objClass, className); Memoize(obj); WriteInitArgs(context, obj); Write(Opcode.Inst); WriteStringPair(classModuleName, className); } else { Save(context, objClass); Memoize(obj); WriteInitArgs(context, obj); Write(Opcode.Obj); } WritePut(obj); object getStateCallable; if (Ops.TryGetAttr(obj, SymbolTable.GetState, out getStateCallable)) { Save(context, Ops.Call(getStateCallable)); } else { Save(context, Ops.GetAttr(context, obj, SymbolTable.Dict)); } Write(Opcode.Build); }
private void SaveGlobalByName(ICallerContext context, object obj, object name) { Debug.Assert(!memo.Contains(Ops.Id(obj))); object moduleName = FindModuleForGlobal(context, obj, name); if (protocol >= 2) { object code; if (PythonCopyReg.ExtensionRegistry.TryGetValue(Tuple.MakeTuple(moduleName, name), out code)) { int intCode = (int)code; if (IsUInt8(code)) { Write(Opcode.Ext1); WriteUInt8(code); } else if (IsUInt16(code)) { Write(Opcode.Ext2); WriteUInt16(code); } else if (IsInt32(code)) { Write(Opcode.Ext4); WriteInt32(code); } else { throw Ops.RuntimeError("unrecognized integer format"); } return; } } Memoize(obj); Write(Opcode.Global); WriteStringPair(moduleName, name); WritePut(obj); }
private void SaveNone(ICallerContext context, object obj) { Debug.Assert(Ops.GetDynamicType(obj).Equals(TypeCache.None), "arg must be None"); Write(Opcode.NoneValue); }
/// <summary> /// Call the appropriate reduce method for obj and pickle the object using /// the resulting data. Use the first available of /// copy_reg.dispatch_table[type(obj)], obj.__reduce_ex__, and obj.__reduce__. /// </summary> private void SaveObject(ICallerContext context, object obj) { Debug.Assert(!memo.Contains(Ops.Id(obj))); Memoize(obj); object reduceCallable, result; DynamicType objType = Ops.GetDynamicType(obj); if (PythonCopyReg.DispatchTable.TryGetValue(objType, out reduceCallable)) { result = Ops.Call(reduceCallable, obj); } else if (Ops.TryGetAttr(obj, SymbolTable.ReduceEx, out reduceCallable)) { if (obj is DynamicType) { result = Ops.Call(reduceCallable, obj, protocol); } else { result = Ops.Call(reduceCallable, protocol); } } else if (Ops.TryGetAttr(obj, SymbolTable.Reduce, out reduceCallable)) { if (obj is DynamicType) { result = Ops.Call(reduceCallable, obj); } else { result = Ops.Call(reduceCallable); } } else { throw Ops.AttributeError("no reduce function found for {0}", obj); } if (objType.Equals(TypeCache.String)) { if (memo.Contains(Ops.Id(obj))) { WriteGet(obj); } else { SaveGlobalByName(context, obj, result); } } else if (result is Tuple) { Tuple rt = (Tuple)result; switch (rt.Count) { case 2: SaveReduce(context, obj, reduceCallable, rt[0], rt[1], null, null, null); break; case 3: SaveReduce(context, obj, reduceCallable, rt[0], rt[1], rt[2], null, null); break; case 4: SaveReduce(context, obj, reduceCallable, rt[0], rt[1], rt[2], rt[3], null); break; case 5: SaveReduce(context, obj, reduceCallable, rt[0], rt[1], rt[2], rt[3], rt[4]); break; default: throw CannotPickle(obj, "tuple returned by {0} must have to to five elements", reduceCallable); } } else { throw CannotPickle(obj, "{0} must return string or tuple", reduceCallable); } }
/// <summary> /// Find the module for obj and ensure that obj is reachable in that module by the given name. /// /// Throw PicklingError if any of the following are true: /// - The module couldn't be determined. /// - The module couldn't be loaded. /// - The given name doesn't exist in the module. /// - The given name is a different object than obj. /// /// Otherwise, return the name of the module. /// /// To determine which module obj lives in, obj.__module__ is used if available. The /// module named by obj.__module__ is loaded if needed. If obj has no __module__ /// attribute, then each loaded module is searched. If a loaded module has an /// attribute with the given name, and that attribute is the same object as obj, /// then that module is used. /// </summary> private object FindModuleForGlobal(ICallerContext context, object obj, object name) { object module; object moduleName; if (Ops.TryGetAttr(obj, SymbolTable.Module, out moduleName)) { if (!Importer.TryGetExistingModule(context.SystemState, Converter.ConvertToString(moduleName), out module)) { module = Builtin.__import__(context, Converter.ConvertToString(moduleName)); } object foundObj; if (Ops.TryGetAttr(module, SymbolTable.StringToId(Converter.ConvertToString(name)), out foundObj)) { if (Ops.IsRetBool(foundObj, obj)) { return moduleName; } else { throw CannotPickle(obj, "it's not the same object as {0}.{1}", moduleName, name); } } else { throw CannotPickle(obj, "it's not found as {0}.{1}", moduleName, name); } } else { // No obj.__module__, so crawl through all loaded modules looking for obj foreach (KeyValuePair<object, object> modulePair in context.SystemState.modules) { moduleName = modulePair.Key; module = modulePair.Value; object foundObj; if (Ops.TryGetAttr(module, SymbolTable.StringToId(Converter.ConvertToString(name)), out foundObj) && Ops.IsRetBool(foundObj, obj) ) { return moduleName; } } throw CannotPickle(obj, "could not determine its module"); } }
/// <summary> /// Pickle the result of a reduce function. /// /// Only context, obj, func, and reduceCallable are required; all other arguments may be null. /// </summary> private void SaveReduce(ICallerContext context, object obj, object reduceCallable, object func, object args, object state, object listItems, object dictItems) { if (!Ops.IsCallable(func)) { throw CannotPickle(obj, "func from reduce() should be callable"); } else if (!(args is Tuple) && args != null) { throw CannotPickle(obj, "args from reduce() should be a tuple"); } else if (listItems != null && !(listItems is IEnumerator)) { throw CannotPickle(obj, "listitems from reduce() should be a list iterator"); } else if (dictItems != null && !(dictItems is IEnumerator)) { throw CannotPickle(obj, "dictitems from reduce() should be a dict iterator"); } object funcName; string funcNameString; if (!Ops.TryGetAttr(func, SymbolTable.Name, out funcName)) { throw CannotPickle(obj, "func from reduce() ({0}) should have a __name__ attribute"); } else if (!Converter.TryConvertToString(funcName, out funcNameString) || funcNameString == null) { throw CannotPickle(obj, "__name__ of func from reduce() must be string"); } if (protocol >= 2 && "__newobj__" == funcNameString) { if (args == null) { throw CannotPickle(obj, "__newobj__ arglist is None"); } Tuple argsTuple = (Tuple)args; if (argsTuple.Count == 0) { throw CannotPickle(obj, "__newobj__ arglist is empty"); } else if (!Ops.GetDynamicType(obj).Equals(argsTuple[0])) { throw CannotPickle(obj, "args[0] from __newobj__ args has the wrong class"); } Save(context, argsTuple[0]); Save(context, argsTuple[new Slice(1, null)]); Write(Opcode.NewObj); } else { Save(context, func); Save(context, args); Write(Opcode.Reduce); } WritePut(obj); if (state != null) { Save(context, state); Write(Opcode.Build); } if (listItems != null) { BatchAppends(context, (IEnumerator)listItems); } if (dictItems != null) { BatchSetItems(context, (IEnumerator)dictItems); } }
/// <summary> /// Emit a series of opcodes that will set all (key, value) pairs indexed by /// iter in the object at the top of the stack. Use SETITEMS if possible, /// but append no more than BatchSize items at a time. /// </summary> private void BatchSetItems(ICallerContext context, IEnumerator enumerator) { Tuple kvTuple; if (protocol < 1) { while (enumerator.MoveNext()) { kvTuple = (Tuple)enumerator.Current; Save(context, kvTuple[0]); Save(context, kvTuple[1]); Write(Opcode.SetItem); } } else { object nextKey, nextValue; if (enumerator.MoveNext()) { kvTuple = (Tuple)enumerator.Current; nextKey = kvTuple[0]; nextValue = kvTuple[1]; } else { return; } int batchCompleted = 0; object curKey, curValue; // We do a one-item lookahead to avoid emitting a SETITEMS for a // single remaining item. while (enumerator.MoveNext()) { curKey = nextKey; curValue = nextValue; kvTuple = (Tuple)enumerator.Current; nextKey = kvTuple[0]; nextValue = kvTuple[1]; if (batchCompleted == BatchSize) { Write(Opcode.SetItems); batchCompleted = 0; } if (batchCompleted == 0) { Write(Opcode.Mark); } Save(context, curKey); Save(context, curValue); batchCompleted++; } if (batchCompleted == BatchSize) { Write(Opcode.SetItems); batchCompleted = 0; } Save(context, nextKey); Save(context, nextValue); batchCompleted++; if (batchCompleted > 1) { Write(Opcode.SetItems); } else { Write(Opcode.SetItem); } } }
private void SaveBoolean(ICallerContext context, object obj) { Debug.Assert(Ops.GetDynamicType(obj).Equals(TypeCache.Boolean), "arg must be bool"); if (protocol < 2) { Write(Opcode.Int); Write(String.Format("0{0}", ((bool)obj) ? 1 : 0)); Write(Newline); } else { if ((bool)obj) { Write(Opcode.NewTrue); } else { Write(Opcode.NewFalse); } } }