/DICK.B1/IronPython.Modules/_weakref.cs
C# | 919 lines | 696 code | 179 blank | 44 comment | 111 complexity | 315f12dd5eb7ef60bee0176ee7d27414 MD5 | raw file
- /* ****************************************************************************
- *
- * Copyright (c) Microsoft Corporation.
- *
- * This source code is subject to terms and conditions of the Microsoft Public License. A
- * copy of the license can be found in the License.html file at the root of this distribution. If
- * you cannot locate the Microsoft Public License, please send an email to
- * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
- * by the terms of the Microsoft Public License.
- *
- * You must not remove this notice, or any other, from this software.
- *
- *
- * ***************************************************************************/
-
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Runtime.CompilerServices;
-
- using IronPython.Runtime;
- using IronPython.Runtime.Exceptions;
- using IronPython.Runtime.Operations;
- using IronPython.Runtime.Types;
- using Microsoft.Scripting;
- using Microsoft.Scripting.Actions;
- using Microsoft.Scripting.Runtime;
- using Microsoft.Scripting.Utils;
-
- [assembly: PythonModule("_weakref", typeof(IronPython.Modules.PythonWeakRef))]
- namespace IronPython.Modules {
- public static partial class PythonWeakRef {
- public const string __doc__ = "Provides support for creating weak references and proxies to objects";
-
- internal static IWeakReferenceable ConvertToWeakReferenceable(object obj) {
- IWeakReferenceable iwr = obj as IWeakReferenceable;
- if (iwr != null) return iwr;
-
- throw PythonOps.TypeError("cannot create weak reference to '{0}' object", PythonOps.GetPythonTypeName(obj));
- }
-
- public static int getweakrefcount(object @object) {
- return @ref.GetWeakRefCount(@object);
- }
-
- public static List getweakrefs(object @object) {
- return @ref.GetWeakRefs(@object);
- }
-
- public static object proxy(CodeContext context, object @object) {
- return proxy(context, @object, null);
- }
-
- public static object proxy(CodeContext context, object @object, object callback) {
- if (PythonOps.IsCallable(context, @object)) {
- return weakcallableproxy.MakeNew(context, @object, callback);
- } else {
- return weakproxy.MakeNew(context, @object, callback);
- }
- }
-
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
- public static readonly PythonType CallableProxyType = DynamicHelpers.GetPythonTypeFromType(typeof(weakcallableproxy));
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
- public static readonly PythonType ProxyType = DynamicHelpers.GetPythonTypeFromType(typeof(weakproxy));
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
- public static readonly PythonType ReferenceType = DynamicHelpers.GetPythonTypeFromType(typeof(@ref));
-
- [PythonType]
- public class @ref : IStructuralEquatable
- #if CLR2
- , IValueEquality
- #endif
- {
- private WeakHandle _target;
- private int _hashVal;
- private bool _fHasHash;
-
- #region Python Constructors
- public static object __new__(CodeContext context, PythonType cls, object @object) {
- IWeakReferenceable iwr = ConvertToWeakReferenceable(@object);
-
- if (cls == DynamicHelpers.GetPythonTypeFromType(typeof(@ref))) {
- WeakRefTracker wrt = iwr.GetWeakRef();
- if (wrt != null) {
- for (int i = 0; i < wrt.HandlerCount; i++) {
- if (wrt.GetHandlerCallback(i) == null && wrt.GetWeakRef(i) is @ref) {
- return wrt.GetWeakRef(i);
- }
- }
- }
-
- return new @ref(@object);
- } else {
- return cls.CreateInstance(context, @object);
- }
- }
-
- public static object __new__(CodeContext context, PythonType cls, object @object, object callback) {
- if (callback == null) return __new__(context, cls, @object);
- if (cls == DynamicHelpers.GetPythonTypeFromType(typeof(@ref))) {
- return new @ref(@object, callback);
- } else {
- return cls.CreateInstance(context, @object, callback);
- }
- }
- #endregion
-
- #region Constructors
- public @ref(object @object)
- : this(@object, null) {
- }
-
- public @ref(object @object, object callback) {
- WeakRefHelpers.InitializeWeakRef(this, @object, callback);
- this._target = new WeakHandle(@object, false);
- }
- #endregion
-
- #region Finalizer
- ~@ref() {
- // remove our self from the chain...
- try {
- if (_target.IsAlive) {
- IWeakReferenceable iwr = _target.Target as IWeakReferenceable;
- if (iwr != null) {
- WeakRefTracker wrt = iwr.GetWeakRef();
- if (wrt != null) {
- // weak reference being finalized before target object,
- // we don't want to run the callback when the object is
- // finalized.
- wrt.RemoveHandler(this);
- }
- }
-
- _target.Free();
- }
- } catch (InvalidOperationException) {
- // target was freed
- }
- }
- #endregion
-
- #region Static helpers
-
- internal static int GetWeakRefCount(object o) {
- IWeakReferenceable iwr = o as IWeakReferenceable;
- if (iwr != null) {
- WeakRefTracker wrt = iwr.GetWeakRef();
- if (wrt != null) return wrt.HandlerCount;
- }
-
- return 0;
- }
-
- internal static List GetWeakRefs(object o) {
- List l = new List();
- IWeakReferenceable iwr = o as IWeakReferenceable;
- if (iwr != null) {
- WeakRefTracker wrt = iwr.GetWeakRef();
- if (wrt != null) {
- for (int i = 0; i < wrt.HandlerCount; i++) {
- l.AddNoLock(wrt.GetWeakRef(i));
- }
- }
- }
- return l;
- }
-
- #endregion
-
- [SpecialName]
- public object Call(CodeContext context) {
- if (!_target.IsAlive) {
- throw PythonOps.ReferenceError("weak object has gone away");
- }
- try {
- object res = _target.Target;
- GC.KeepAlive(this);
- return res;
- } catch (InvalidOperationException) {
- throw PythonOps.ReferenceError("weak object has gone away");
- }
- }
-
- [return: MaybeNotImplemented]
- public static NotImplementedType operator >(@ref self, object other) {
- return PythonOps.NotImplemented;
- }
-
- [return: MaybeNotImplemented]
- public static NotImplementedType operator <(@ref self, object other) {
- return PythonOps.NotImplemented;
- }
-
- [return: MaybeNotImplemented]
- public static NotImplementedType operator <=(@ref self, object other) {
- return PythonOps.NotImplemented;
- }
-
- [return: MaybeNotImplemented]
- public static NotImplementedType operator >=(@ref self, object other) {
- return PythonOps.NotImplemented;
- }
-
- #region IValueEquality Members
- #if CLR2
- int IValueEquality.GetValueHashCode() {
- return __hash__(DefaultContext.Default);
- }
-
- bool IValueEquality.ValueEquals(object other) {
- return EqualsWorker(other, null);
- }
- #endif
- #endregion
-
- #region IStructuralEquatable Members
-
- /// <summary>
- /// Special hash function because IStructuralEquatable.GetHashCode is not allowed to throw.
- /// </summary>
- public int __hash__(CodeContext/*!*/ context) {
- if (!_fHasHash) {
- object refObj = _target.Target;
- if (refObj == null) throw PythonOps.TypeError("weak object has gone away");
- GC.KeepAlive(this);
- _hashVal = PythonContext.GetContext(context).EqualityComparerNonGeneric.GetHashCode(refObj);
- _fHasHash = true;
- }
- return _hashVal;
- }
-
- int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) {
- if (!_fHasHash) {
- object refObj = _target.Target;
- GC.KeepAlive(this);
- _hashVal = comparer.GetHashCode(refObj);
- _fHasHash = true;
- }
- return _hashVal;
- }
-
- bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) {
- return EqualsWorker(other, comparer);
- }
-
- private bool EqualsWorker(object other, IEqualityComparer comparer) {
- if (object.ReferenceEquals(this, other)) {
- return true;
- }
-
- bool fResult = false;
- @ref wr = other as @ref;
- if (wr != null) {
- object ourTarget = _target.Target;
- object itsTarget = wr._target.Target;
-
- GC.KeepAlive(this);
- GC.KeepAlive(wr);
- if (ourTarget != null && itsTarget != null) {
- fResult = RefEquals(ourTarget, itsTarget, comparer);
- }
- }
- GC.KeepAlive(this);
- return fResult;
- }
-
- /// <summary>
- /// Special equals because none of the special cases in Ops.Equals
- /// are applicable here, and the reference equality check breaks some tests.
- /// </summary>
- private static bool RefEquals(object x, object y, IEqualityComparer comparer) {
- CodeContext context;
- if (comparer != null && comparer is PythonContext.PythonEqualityComparer) {
- context = ((PythonContext.PythonEqualityComparer)comparer).Context.SharedContext;
- } else {
- context = DefaultContext.Default;
- }
-
- object ret;
- if (PythonTypeOps.TryInvokeBinaryOperator(context, x, y, "__eq__", out ret) &&
- ret != NotImplementedType.Value) {
- return (bool)ret;
- }
-
- if (PythonTypeOps.TryInvokeBinaryOperator(context, y, x, "__eq__", out ret) &&
- ret != NotImplementedType.Value) {
- return (bool)ret;
- }
-
- if (comparer != null) {
- return comparer.Equals(x, y);
- }
-
- return x.Equals(y);
- }
-
-
- #endregion
- }
-
- [PythonType, DynamicBaseTypeAttribute, PythonHidden]
- public sealed partial class weakproxy : IPythonObject, ICodeFormattable, IProxyObject, IPythonMembersList, IStructuralEquatable
- #if CLR2
- , IValueEquality
- #endif
- {
- private readonly WeakHandle _target;
- private readonly CodeContext/*!*/ _context;
-
- #region Python Constructors
- internal static object MakeNew(CodeContext/*!*/ context, object @object, object callback) {
- IWeakReferenceable iwr = ConvertToWeakReferenceable(@object);
-
- if (callback == null) {
- WeakRefTracker wrt = iwr.GetWeakRef();
- if (wrt != null) {
- for (int i = 0; i < wrt.HandlerCount; i++) {
- if (wrt.GetHandlerCallback(i) == null && wrt.GetWeakRef(i) is weakproxy) {
- return wrt.GetWeakRef(i);
- }
- }
- }
- }
-
- return new weakproxy(context, @object, callback);
- }
- #endregion
-
- #region Constructors
-
- private weakproxy(CodeContext/*!*/ context, object target, object callback) {
- WeakRefHelpers.InitializeWeakRef(this, target, callback);
- _target = new WeakHandle(target, false);
- _context = context;
- }
- #endregion
-
- #region Finalizer
- ~weakproxy() {
- // remove our self from the chain...
- try {
- IWeakReferenceable iwr = _target.Target as IWeakReferenceable;
- if (iwr != null) {
- WeakRefTracker wrt = iwr.GetWeakRef();
- wrt.RemoveHandler(this);
- }
-
- _target.Free();
- } catch (InvalidOperationException) {
- // target was freed
- }
- }
- #endregion
-
- #region private members
- /// <summary>
- /// gets the object or throws a reference exception
- /// </summary>
- object GetObject() {
- object res;
- if (!TryGetObject(out res)) {
- throw PythonOps.ReferenceError("weakly referenced object no longer exists");
- }
- return res;
- }
-
- bool TryGetObject(out object result) {
- try {
- result = _target.Target;
- if (result == null) return false;
- GC.KeepAlive(this);
- return true;
- } catch (InvalidOperationException) {
- result = null;
- return false;
- }
- }
- #endregion
-
- #region IPythonObject Members
-
- PythonDictionary IPythonObject.Dict {
- get {
- IPythonObject sdo = GetObject() as IPythonObject;
- if (sdo != null) {
- return sdo.Dict;
- }
-
- return null;
- }
- }
-
- PythonDictionary IPythonObject.SetDict(PythonDictionary dict) {
- return (GetObject() as IPythonObject).SetDict(dict);
- }
-
- bool IPythonObject.ReplaceDict(PythonDictionary dict) {
- return (GetObject() as IPythonObject).ReplaceDict(dict);
- }
-
- void IPythonObject.SetPythonType(PythonType newType) {
- (GetObject() as IPythonObject).SetPythonType(newType);
- }
-
- PythonType IPythonObject.PythonType {
- get {
- return DynamicHelpers.GetPythonTypeFromType(typeof(weakproxy));
- }
- }
-
- object[] IPythonObject.GetSlots() { return null; }
- object[] IPythonObject.GetSlotsCreate() { return null; }
-
- #endregion
-
- #region object overloads
-
- public override string ToString() {
- return PythonOps.ToString(GetObject());
- }
-
- #endregion
-
- #region ICodeFormattable Members
-
- public string/*!*/ __repr__(CodeContext/*!*/ context) {
- object obj = _target.Target;
- GC.KeepAlive(this);
- return String.Format("<weakproxy at {0} to {1} at {2}>",
- IdDispenser.GetId(this),
- PythonOps.GetPythonTypeName(obj),
- IdDispenser.GetId(obj));
- }
-
- #endregion
-
- #region Custom member access
-
- [SpecialName]
- public object GetCustomMember(CodeContext/*!*/ context, string name) {
- object value, o = GetObject();
- if (PythonOps.TryGetBoundAttr(context, o, name, out value)) {
- return value;
- }
-
- return OperationFailed.Value;
- }
-
- [SpecialName]
- public void SetMember(CodeContext/*!*/ context, string name, object value) {
- object o = GetObject();
- PythonOps.SetAttr(context, o, name, value);
- }
-
- [SpecialName]
- public void DeleteMember(CodeContext/*!*/ context, string name) {
- object o = GetObject();
- PythonOps.DeleteAttr(context, o, name);
- }
-
- IList<string> IMembersList.GetMemberNames() {
- return PythonOps.GetStringMemberList(this);
- }
-
- IList<object> IPythonMembersList.GetMemberNames(CodeContext/*!*/ context) {
- object o;
- if (!TryGetObject(out o)) {
- // if we've been disconnected return an empty list
- return new List();
- }
-
- return PythonOps.GetAttrNames(context, o);
- }
-
- #endregion
-
- #region IProxyObject Members
-
- object IProxyObject.Target {
- get { return GetObject(); }
- }
-
- #endregion
-
- #region IValueEquality Members
- #if CLR2
- int IValueEquality.GetValueHashCode() {
- throw PythonOps.TypeErrorForUnhashableType("weakproxy");
- }
-
- bool IValueEquality.ValueEquals(object other) {
- weakproxy wrp = other as weakproxy;
- if (wrp != null) return EqualsWorker(wrp);
-
- return PythonOps.EqualRetBool(_context, GetObject(), other);
- }
- #endif
- #endregion
-
- #region IStructuralEquatable Members
-
- public const object __hash__ = null;
-
- private bool EqualsWorker(weakproxy other) {
- return PythonOps.EqualRetBool(_context, GetObject(), other.GetObject());
- }
-
- /// <summary>
- /// Special equality function because IStructuralEquatable.Equals is not allowed to throw.
- /// </summary>
- [return: MaybeNotImplemented]
- public object __eq__(object other) {
- if (!(other is weakproxy)) return NotImplementedType.Value;
-
- return ScriptingRuntimeHelpers.BooleanToObject(EqualsWorker((weakproxy)other));
- }
-
- [return: MaybeNotImplemented]
- public object __ne__(object other) {
- if (!(other is weakproxy)) return NotImplementedType.Value;
-
- return ScriptingRuntimeHelpers.BooleanToObject(!EqualsWorker((weakproxy)other));
- }
-
- int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) {
- object obj;
- if (TryGetObject(out obj)) {
- return comparer.GetHashCode(obj);
- }
- return comparer.GetHashCode(null);
- }
-
- bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) {
- object obj;
- if (!TryGetObject(out obj)) {
- obj = null;
- }
-
- weakproxy wrp = other as weakproxy;
- if (wrp != null) {
- object otherObj;
- if (!TryGetObject(out otherObj)) {
- otherObj = null;
- }
-
- return comparer.Equals(obj, otherObj);
- }
-
- return comparer.Equals(obj, other);
- }
-
- #endregion
-
- public object __nonzero__() {
- return Converter.ConvertToBoolean(GetObject());
- }
-
- public static explicit operator bool(weakproxy self) {
- return Converter.ConvertToBoolean(self.GetObject());
- }
- }
-
- [PythonType, DynamicBaseTypeAttribute, PythonHidden]
- public sealed partial class weakcallableproxy :
- IPythonObject,
- ICodeFormattable,
- IProxyObject,
- IStructuralEquatable,
- #if CLR2
- IValueEquality,
- #endif
- IPythonMembersList {
-
- private WeakHandle _target;
- private readonly CodeContext/*!*/ _context;
-
- #region Python Constructors
-
- internal static object MakeNew(CodeContext/*!*/ context, object @object, object callback) {
- IWeakReferenceable iwr = ConvertToWeakReferenceable(@object);
-
- if (callback == null) {
- WeakRefTracker wrt = iwr.GetWeakRef();
- if (wrt != null) {
- for (int i = 0; i < wrt.HandlerCount; i++) {
-
- if (wrt.GetHandlerCallback(i) == null &&
- wrt.GetWeakRef(i) is weakcallableproxy) {
- return wrt.GetWeakRef(i);
- }
- }
- }
- }
-
- return new weakcallableproxy(context, @object, callback);
- }
-
- #endregion
-
- #region Constructors
-
- private weakcallableproxy(CodeContext context, object target, object callback) {
- WeakRefHelpers.InitializeWeakRef(this, target, callback);
- _target = new WeakHandle(target, false);
- _context = context;
- }
-
- #endregion
-
- #region Finalizer
-
- ~weakcallableproxy() {
- // remove our self from the chain...
- try {
- IWeakReferenceable iwr = _target.Target as IWeakReferenceable;
- if (iwr != null) {
- WeakRefTracker wrt = iwr.GetWeakRef();
- wrt.RemoveHandler(this);
- }
- _target.Free();
- } catch (InvalidOperationException) {
- // target was freed
- }
- }
-
- #endregion
-
- #region private members
-
- /// <summary>
- /// gets the object or throws a reference exception
- /// </summary>
- private object GetObject() {
- object res;
- if (!TryGetObject(out res)) {
- throw PythonOps.ReferenceError("weakly referenced object no longer exists");
- }
- return res;
- }
-
- private bool TryGetObject(out object result) {
- try {
- result = _target.Target;
- if (result == null) return false;
- GC.KeepAlive(this);
- return true;
- } catch (InvalidOperationException) {
- result = null;
- return false;
- }
- }
-
- #endregion
-
- #region IPythonObject Members
-
- PythonDictionary IPythonObject.Dict {
- get {
- return (GetObject() as IPythonObject).Dict;
- }
- }
-
- PythonDictionary IPythonObject.SetDict(PythonDictionary dict) {
- return (GetObject() as IPythonObject).SetDict(dict);
- }
-
- bool IPythonObject.ReplaceDict(PythonDictionary dict) {
- return (GetObject() as IPythonObject).ReplaceDict(dict);
- }
-
- void IPythonObject.SetPythonType(PythonType newType) {
- (GetObject() as IPythonObject).SetPythonType(newType);
- }
-
- PythonType IPythonObject.PythonType {
- get {
- return DynamicHelpers.GetPythonTypeFromType(typeof(weakcallableproxy));
- }
- }
-
- object[] IPythonObject.GetSlots() { return null; }
- object[] IPythonObject.GetSlotsCreate() { return null; }
-
- #endregion
-
- #region object overloads
-
- public override string ToString() {
- return PythonOps.ToString(GetObject());
- }
-
- #endregion
-
- #region ICodeFormattable Members
-
- public string/*!*/ __repr__(CodeContext/*!*/ context) {
- object obj = _target.Target;
- GC.KeepAlive(this);
- return String.Format("<weakproxy at {0} to {1} at {2}>",
- IdDispenser.GetId(this),
- PythonOps.GetPythonTypeName(obj),
- IdDispenser.GetId(obj));
- }
-
- #endregion
-
- [SpecialName]
- public object Call(CodeContext/*!*/ context, params object[] args) {
- return PythonContext.GetContext(context).CallSplat(GetObject(), args);
- }
-
- [SpecialName]
- public object Call(CodeContext/*!*/ context, [ParamDictionary]IDictionary<object, object> dict, params object[] args) {
- return PythonCalls.CallWithKeywordArgs(context, GetObject(), args, dict);
- }
-
- #region Custom members access
-
- [SpecialName]
- public object GetCustomMember(CodeContext/*!*/ context, string name) {
- object o = GetObject();
- object value;
- if (PythonOps.TryGetBoundAttr(context, o, name, out value)) {
- return value;
- }
- return OperationFailed.Value;
- }
-
- [SpecialName]
- public void SetMember(CodeContext/*!*/ context, string name, object value) {
- object o = GetObject();
- PythonOps.SetAttr(context, o, name, value);
- }
-
- [SpecialName]
- public void DeleteMember(CodeContext/*!*/ context, string name) {
- object o = GetObject();
- PythonOps.DeleteAttr(context, o, name);
- }
-
- IList<string> IMembersList.GetMemberNames() {
- return PythonOps.GetStringMemberList(this);
- }
-
- IList<object> IPythonMembersList.GetMemberNames(CodeContext/*!*/ context) {
- object o;
- if (!TryGetObject(out o)) {
- // if we've been disconnected return an empty list
- return new List();
- }
-
- return PythonOps.GetAttrNames(context, o);
- }
-
- #endregion
-
- #region IProxyObject Members
-
- object IProxyObject.Target {
- get { return GetObject(); }
- }
-
- #endregion
-
- #region IValueEquality Members
- #if CLR2
- int IValueEquality.GetValueHashCode() {
- throw PythonOps.TypeErrorForUnhashableType("weakcallableproxy");
- }
-
- bool IValueEquality.ValueEquals(object other) {
- return __eq__(other);
- }
- #endif
- #endregion
-
- #region IStructuralEquatable Members
-
- public const object __hash__ = null;
-
- /// <summary>
- /// Special equality function because IStructuralEquatable.Equals is not allowed to throw.
- /// </summary>
- public bool __eq__(object other) {
- weakcallableproxy wrp = other as weakcallableproxy;
- if (wrp != null) return GetObject().Equals(wrp.GetObject());
-
- return PythonOps.EqualRetBool(_context, GetObject(), other);
- }
-
- public bool __ne__(object other) {
- return !__eq__(other);
- }
-
- int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) {
- object obj;
- if (TryGetObject(out obj)) {
- return comparer.GetHashCode(obj);
- }
- return comparer.GetHashCode(null);
- }
-
- bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) {
- object obj;
- if (!TryGetObject(out obj)) {
- obj = null;
- }
-
- weakcallableproxy wrp = other as weakcallableproxy;
- if (wrp != null) {
- object otherObj;
- if (!TryGetObject(out otherObj)) {
- otherObj = null;
- }
-
- return comparer.Equals(obj, otherObj);
- }
-
- return comparer.Equals(obj, other);
- }
-
- #endregion
-
- public object __nonzero__() {
- return Converter.ConvertToBoolean(GetObject());
- }
- }
-
- static class WeakRefHelpers {
- public static void InitializeWeakRef(object self, object target, object callback) {
- IWeakReferenceable iwr = ConvertToWeakReferenceable(target);
-
- WeakRefTracker wrt = iwr.GetWeakRef();
- if (wrt == null) {
- if (!iwr.SetWeakRef(new WeakRefTracker(callback, self))) {
- throw PythonOps.TypeError("cannot create weak reference to '{0}' object", PythonOps.GetPythonTypeName(target));
- }
- } else {
- wrt.ChainCallback(callback, self);
- }
- }
- }
- }
-
- [PythonType("wrapper_descriptor")]
- class SlotWrapper : PythonTypeSlot, ICodeFormattable {
- private readonly string _name;
- private readonly PythonType _type;
-
- public SlotWrapper(string slotName, PythonType targetType) {
- _name = slotName;
- _type = targetType;
- }
-
- #region ICodeFormattable Members
-
- public virtual string/*!*/ __repr__(CodeContext/*!*/ context) {
- return String.Format("<slot wrapper {0} of {1} objects>",
- PythonOps.Repr(context, _name),
- PythonOps.Repr(context, _type.Name));
- }
-
- #endregion
-
- #region PythonTypeSlot Overrides
-
- internal override bool TryGetValue(CodeContext context, object instance, PythonType owner, out object value) {
- if (instance == null) {
- value = this;
- return true;
- }
-
- IProxyObject proxy = instance as IProxyObject;
-
- if (proxy == null)
- throw PythonOps.TypeError("descriptor for {0} object doesn't apply to {1} object",
- PythonOps.Repr(context, _type.Name),
- PythonOps.Repr(context, PythonTypeOps.GetName(instance)));
-
- if (!DynamicHelpers.GetPythonType(proxy.Target).TryGetBoundMember(context, proxy.Target, _name, out value))
- return false;
-
- value = new GenericMethodWrapper(_name, proxy);
- return true;
- }
-
- #endregion
- }
-
- [PythonType("method-wrapper")]
- public class GenericMethodWrapper {
- string name;
- IProxyObject target;
-
- public GenericMethodWrapper(string methodName, IProxyObject proxyTarget) {
- name = methodName;
- target = proxyTarget;
- }
-
- [SpecialName]
- public object Call(CodeContext context, params object[] args) {
- return PythonOps.Invoke(context, target.Target, name, args);
- }
-
-
- [SpecialName]
- public object Call(CodeContext context, [ParamDictionary]IDictionary<object, object> dict, params object[] args) {
- object targetMethod;
- if (!DynamicHelpers.GetPythonType(target.Target).TryGetBoundMember(context, target.Target, name, out targetMethod))
- throw PythonOps.AttributeError("type {0} has no attribute {1}",
- DynamicHelpers.GetPythonType(target.Target),
- name);
-
- return PythonCalls.CallWithKeywordArgs(context, targetMethod, args, dict);
- }
- }
- }