[Python.NET] Re: Wrap in interface (#1240)

Victor “LOST” Milovanov <[email protected]> Mon, 2 Nov 2020 18:35:27 -0800
Newsgroups gmane.comp.python.dotnet
Message-ID <[email protected]>
--===============8119071126935586326==
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset="utf-8"

<html xmlns:o=3D"urn:schemas-microsoft-com:office:office" xmlns:w=3D"urn:sc=
hemas-microsoft-com:office:word" xmlns:m=3D"http://schemas.microsoft.com/of=
fice/2004/12/omml" xmlns=3D"http://www.w3.org/TR/REC-html40"><head><meta ht=
tp-equiv=3DContent-Type content=3D"text/html; charset=3Dutf-8"><meta name=
=3DGenerator content=3D"Microsoft Word 15 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
	{font-family:"Cambria Math";
	panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
	{font-family:Calibri;
	panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
	{margin:0in;
	font-size:11.0pt;
	font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
	{mso-style-priority:99;
	color:blue;
	text-decoration:underline;}
.MsoChpDefault
	{mso-style-type:export-only;}
@page WordSection1
	{size:8.5in 11.0in;
	margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
	{page:WordSection1;}
--></style></head><body lang=3DEN-US link=3Dblue vlink=3D"#954F72"><div cla=
ss=3DWordSection1><p class=3DMsoNormal>The original bug report described a =
similar problem, except the behavior without defaulting to stricter interfa=
ce types is very unintuitive. Imagine you have a well documented library, t=
hat exposes property <b>Prop</b> of type <b>IInterface</b>. When specific c=
lass implements some <b>Method</b> =C2=A0in <b>IInterface</b> explicitly (w=
hich arguably is a very minor implementation detail), and you call <b>Prop.=
Method()</b> in Python, it can fail with AttributeError despite the documen=
tation claiming this method exists on the interface. This is very confusing=
. IMHO, more confusing, than inability to get Length of an element of <b>IS=
hape[]</b>.<b><o:p></o:p></b></p><p class=3DMsoNormal><o:p>&nbsp;</o:p></p>=
<p class=3DMsoNormal>We could try to improve the situation for Python folks=
 by allowing interface instance wrappers to fall back to the original class=
 instance in case the attribute is not found in the interface itself. I thi=
nk this might still be problematic, as it would make the behavior of hasatt=
r and other similar functions a bit surprising.<o:p></o:p></p><p class=3DMs=
oNormal><o:p>&nbsp;</o:p></p><p class=3DMsoNormal>Regardless, there=E2=80=
=99s a workaround for the scenario you described which is just doing <b>m.G=
etShape(1).__raw_implementation__.Length </b>or <o:p></o:p></p><p class=3DM=
soNormal><b>m.GetShape(1).__implementation__.Length </b>depending if you ne=
ed an encoded instance.<o:p></o:p></p><p class=3DMsoNormal><o:p>&nbsp;</o:p=
></p><p class=3DMsoNormal>Regards,<o:p></o:p></p><p class=3DMsoNormal>Victo=
r Milovanov<o:p></o:p></p><p class=3DMsoNormal><o:p>&nbsp;</o:p></p><div st=
yle=3D'mso-element:para-border-div;border:none;border-top:solid #E1E1E1 1.0=
pt;padding:3.0pt 0in 0in 0in'><p class=3DMsoNormal style=3D'border:none;pad=
ding:0in'><b>From: </b><a href=3D"mailto:[email protected]">Mohamed =
Koubaa</a><br><b>Sent: </b>Monday, November 2, 2020 6:15 PM<br><b>To: </b><=
a href=3D"mailto:[email protected]">[email protected]</a><br><b>Subje=
ct: </b>[Python.NET] Wrap in interface (#1240)</p></div><p class=3DMsoNorma=
l><o:p>&nbsp;</o:p></p><div><p class=3DMsoNormal><span style=3D'font-size:1=
2.0pt;color:black'>Hello,<o:p></o:p></span></p></div><div><p class=3DMsoNor=
mal><span style=3D'font-size:12.0pt;color:black'><o:p>&nbsp;</o:p></span></=
p></div><div><p class=3DMsoNormal><span style=3D'font-size:12.0pt;color:bla=
ck'>This <a href=3D"https://github.com/pythonnet/pythonnet/pull/1240" title=
=3D"https://github.com/pythonnet/pythonnet/pull/1240">PR</a>&nbsp;changed b=
ehavior of pythonnet to use stricter typing when a method returns an interf=
ace.&nbsp; I'd like a way to opt-out of this behavior, and I'll share a rep=
resentative use-case below.&nbsp; The tl;dr is that python is a dynamic lan=
guage and I expect the C# objects which pythonnet wraps to behave more like=
 &quot;dynamic&quot; and less like the static types on the interface.<o:p><=
/o:p></span></p></div><div><p class=3DMsoNormal><span style=3D'font-size:12=
.0pt;color:black'><o:p>&nbsp;</o:p></span></p></div><div><p class=3DMsoNorm=
al><span style=3D'font-size:12.0pt;color:black'>**** C# code ****<o:p></o:p=
></span></p></div><div><p class=3DMsoNormal><span style=3D'font-size:12.0pt=
;font-family:"Courier New";color:black'>namespace Example1</span><span styl=
e=3D'font-size:12.0pt;color:black'> <o:p></o:p></span></p><div><p class=3DM=
soNormal><span style=3D'font-size:12.0pt;font-family:"Courier New";color:bl=
ack'>{</span><span style=3D'font-size:12.0pt;color:black'><o:p></o:p></span=
></p></div><div><p class=3DMsoNormal><span style=3D'font-size:12.0pt;font-f=
amily:"Courier New";color:black'>&nbsp; &nbsp; public enum ShapeType</span>=
<span style=3D'font-size:12.0pt;color:black'><o:p></o:p></span></p></div><d=
iv><p class=3DMsoNormal><span style=3D'font-size:12.0pt;font-family:"Courie=
r New";color:black'>&nbsp; &nbsp; {</span><span style=3D'font-size:12.0pt;c=
olor:black'><o:p></o:p></span></p></div><div><p class=3DMsoNormal><span sty=
le=3D'font-size:12.0pt;font-family:"Courier New";color:black'>&nbsp; &nbsp;=
 &nbsp; &nbsp; Square,</span><span style=3D'font-size:12.0pt;color:black'><=
o:p></o:p></span></p></div><div><p class=3DMsoNormal><span style=3D'font-si=
ze:12.0pt;font-family:"Courier New";color:black'>&nbsp; &nbsp; &nbsp; &nbsp=
; Circle</span><span style=3D'font-size:12.0pt;color:black'><o:p></o:p></sp=
an></p></div><div><p class=3DMsoNormal><span style=3D'font-size:12.0pt;font=
-family:"Courier New";color:black'>&nbsp; &nbsp; }</span><span style=3D'fon=
t-size:12.0pt;color:black'><o:p></o:p></span></p></div><div><p class=3DMsoN=
ormal><span style=3D'font-size:12.0pt;font-family:"Courier New";color:black=
'>&nbsp; &nbsp; public interface IShape</span><span style=3D'font-size:12.0=
pt;color:black'><o:p></o:p></span></p></div><div><p class=3DMsoNormal><span=
 style=3D'font-size:12.0pt;font-family:"Courier New";color:black'>&nbsp; &n=
bsp; {</span><span style=3D'font-size:12.0pt;color:black'><o:p></o:p></span=
></p></div><div><p class=3DMsoNormal><span style=3D'font-size:12.0pt;font-f=
amily:"Courier New";color:black'>&nbsp; &nbsp; &nbsp; &nbsp; void Draw();</=
span><span style=3D'font-size:12.0pt;color:black'><o:p></o:p></span></p></d=
iv><div><p class=3DMsoNormal><span style=3D'font-size:12.0pt;color:black'><=
o:p>&nbsp;</o:p></span></p></div><div><p class=3DMsoNormal><span style=3D'f=
ont-size:12.0pt;font-family:"Courier New";color:black'>&nbsp; &nbsp; &nbsp;=
 &nbsp; double Area { get; }</span><span style=3D'font-size:12.0pt;color:bl=
ack'><o:p></o:p></span></p></div><div><p class=3DMsoNormal><span style=3D'f=
ont-size:12.0pt;color:black'><o:p>&nbsp;</o:p></span></p></div><div><p clas=
s=3DMsoNormal><span style=3D'font-size:12.0pt;font-family:"Courier New";col=
or:black'>&nbsp; &nbsp; &nbsp; &nbsp; ShapeType Type { get; }</span><span s=
tyle=3D'font-size:12.0pt;color:black'><o:p></o:p></span></p></div><div><p c=
lass=3DMsoNormal><span style=3D'font-size:12.0pt;font-family:"Courier New";=
color:black'>&nbsp; &nbsp; }</span><span style=3D'font-size:12.0pt;color:bl=
ack'><o:p></o:p></span></p></div><div><p class=3DMsoNormal><span style=3D'f=
ont-size:12.0pt;color:black'><o:p>&nbsp;</o:p></span></p></div><div><p clas=
s=3DMsoNormal><span style=3D'font-size:12.0pt;font-family:"Courier New";col=
or:black'>&nbsp; &nbsp; public class Square : IShape</span><span style=3D'f=
ont-size:12.0pt;color:black'><o:p></o:p></span></p></div><div><p class=3DMs=
oNormal><span style=3D'font-size:12.0pt;font-family:"Courier New";color:bla=
ck'>&nbsp; &nbsp; {</span><span style=3D'font-size:12.0pt;color:black'><o:p=
></o:p></span></p></div><div><p class=3DMsoNormal><span style=3D'font-size:=
12.0pt;font-family:"Courier New";color:black'>&nbsp; &nbsp; &nbsp; &nbsp; p=
ublic double Length { get; }</span><span style=3D'font-size:12.0pt;color:bl=
ack'><o:p></o:p></span></p></div><div><p class=3DMsoNormal><span style=3D'f=
ont-size:12.0pt;font-family:"Courier New";color:black'>&nbsp; &nbsp; &nbsp;=
 &nbsp; public Square(double length)</span><span style=3D'font-size:12.0pt;=
color:black'><o:p></o:p></span></p></div><div><p class=3DMsoNormal><span st=
yle=3D'font-size:12.0pt;font-family:"Courier New";color:black'>&nbsp; &nbsp=
; &nbsp; &nbsp; {</span><span style=3D'font-size:12.0pt;color:black'><o:p><=
/o:p></span></p></div><div><p class=3DMsoNormal><span style=3D'font-size:12=
.0pt;font-family:"Courier New";color:black'>&nbsp; &nbsp; &nbsp; &nbsp; &nb=
sp; &nbsp; Length =3D length;</span><span style=3D'font-size:12.0pt;color:b=
lack'><o:p></o:p></span></p></div><div><p class=3DMsoNormal><span style=3D'=
font-size:12.0pt;font-family:"Courier New";color:black'>&nbsp; &nbsp; &nbsp=
; &nbsp; }</span><span style=3D'font-size:12.0pt;color:black'><o:p></o:p></=
span></p></div><div><p class=3DMsoNormal><span style=3D'font-size:12.0pt;co=
lor:black'><o:p>&nbsp;</o:p></span></p></div><div><p class=3DMsoNormal><spa=
n style=3D'font-size:12.0pt;font-family:"Courier New";color:black'>&nbsp; &=
nbsp; &nbsp; &nbsp; public void Draw() {}</span><span style=3D'font-size:12=
.0pt;color:black'><o:p></o:p></span></p></div><div><p class=3DMsoNormal><sp=
an style=3D'font-size:12.0pt;font-family:"Courier New";color:black'>&nbsp; =
&nbsp; &nbsp; &nbsp; public double Area { get { return Length * Length; } }=
</span><span style=3D'font-size:12.0pt;color:black'><o:p></o:p></span></p><=
/div><div><p class=3DMsoNormal><span style=3D'font-size:12.0pt;font-family:=
"Courier New";color:black'>&nbsp; &nbsp; &nbsp; &nbsp; public ShapeType Typ=
e { get { return ShapeType.Square; } }</span><span style=3D'font-size:12.0p=
t;color:black'><o:p></o:p></span></p></div><div><p class=3DMsoNormal><span =
style=3D'font-size:12.0pt;font-family:"Courier New";color:black'>&nbsp; &nb=
sp; }</span><span style=3D'font-size:12.0pt;color:black'><o:p></o:p></span>=
</p></div><div><p class=3DMsoNormal><span style=3D'font-size:12.0pt;color:b=
lack'><o:p>&nbsp;</o:p></span></p></div><div><p class=3DMsoNormal><span sty=
le=3D'font-size:12.0pt;font-family:"Courier New";color:black'>&nbsp; &nbsp;=
 public class Circle : IShape</span><span style=3D'font-size:12.0pt;color:b=
lack'><o:p></o:p></span></p></div><div><p class=3DMsoNormal><span style=3D'=
font-size:12.0pt;font-family:"Courier New";color:black'>&nbsp; &nbsp; {</sp=
an><span style=3D'font-size:12.0pt;color:black'><o:p></o:p></span></p></div=
><div><p class=3DMsoNormal><span style=3D'font-size:12.0pt;font-family:"Cou=
rier New";color:black'>&nbsp; &nbsp; &nbsp; &nbsp; public double Radius { g=
et; }</span><span style=3D'font-size:12.0pt;color:black'><o:p></o:p></span>=
</p></div><div><p class=3DMsoNormal><span style=3D'font-size:12.0pt;font-fa=
mily:"Courier New";color:black'>&nbsp; &nbsp; &nbsp; &nbsp; public Circle(d=
ouble radius)</span><span style=3D'font-size:12.0pt;color:black'><o:p></o:p=
></span></p></div><div><p class=3DMsoNormal><span style=3D'font-size:12.0pt=
;font-family:"Courier New";color:black'>&nbsp; &nbsp; &nbsp; &nbsp; {</span=
><span style=3D'font-size:12.0pt;color:black'><o:p></o:p></span></p></div><=
div><p class=3DMsoNormal><span style=3D'font-size:12.0pt;font-family:"Couri=
er New";color:black'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Radius =3D r=
adius;</span><span style=3D'font-size:12.0pt;color:black'><o:p></o:p></span=
></p></div><div><p class=3DMsoNormal><span style=3D'font-size:12.0pt;font-f=
amily:"Courier New";color:black'>&nbsp; &nbsp; &nbsp; &nbsp; }</span><span =
style=3D'font-size:12.0pt;color:black'><o:p></o:p></span></p></div><div><p =
class=3DMsoNormal><span style=3D'font-size:12.0pt;color:black'><o:p>&nbsp;<=
/o:p></span></p></div><div><p class=3DMsoNormal><span style=3D'font-size:12=
.0pt;font-family:"Courier New";color:black'>&nbsp; &nbsp; &nbsp; &nbsp; pub=
lic void Draw() {}</span><span style=3D'font-size:12.0pt;color:black'><o:p>=
</o:p></span></p></div><div><p class=3DMsoNormal><span style=3D'font-size:1=
2.0pt;font-family:"Courier New";color:black'>&nbsp; &nbsp; &nbsp; &nbsp; pu=
blic double Area { get { return Math.PI * Radius * Radius; } }</span><span =
style=3D'font-size:12.0pt;color:black'><o:p></o:p></span></p></div><div><p =
class=3DMsoNormal><span style=3D'font-size:12.0pt;font-family:"Courier New"=
;color:black'>&nbsp; &nbsp; &nbsp; &nbsp; public ShapeType Type { get { ret=
urn ShapeType.Circle; } }</span><span style=3D'font-size:12.0pt;color:black=
'><o:p></o:p></span></p></div><div><p class=3DMsoNormal><span style=3D'font=
-size:12.0pt;font-family:"Courier New";color:black'>&nbsp; &nbsp; }</span><=
span style=3D'font-size:12.0pt;color:black'><o:p></o:p></span></p></div><di=
v><p class=3DMsoNormal><span style=3D'font-size:12.0pt;color:black'><o:p>&n=
bsp;</o:p></span></p></div><div><p class=3DMsoNormal><span style=3D'font-si=
ze:12.0pt;font-family:"Courier New";color:black'>&nbsp; &nbsp; public class=
 ShapeDataModel</span><span style=3D'font-size:12.0pt;color:black'><o:p></o=
:p></span></p></div><div><p class=3DMsoNormal><span style=3D'font-size:12.0=
pt;font-family:"Courier New";color:black'>&nbsp; &nbsp; {</span><span style=
=3D'font-size:12.0pt;color:black'><o:p></o:p></span></p></div><div><p class=
=3DMsoNormal><span style=3D'font-size:12.0pt;font-family:"Courier New";colo=
r:black'>&nbsp; &nbsp; &nbsp; &nbsp; private Dictionary&lt;int, IShape&gt; =
_shapes =3D new Dictionary&lt;int, IShape&gt;();</span><span style=3D'font-=
size:12.0pt;color:black'><o:p></o:p></span></p></div><div><p class=3DMsoNor=
mal><span style=3D'font-size:12.0pt;font-family:"Courier New";color:black'>=
&nbsp; &nbsp; &nbsp; &nbsp; private int _nextId =3D 1;</span><span style=3D=
'font-size:12.0pt;color:black'><o:p></o:p></span></p></div><div><p class=3D=
MsoNormal><span style=3D'font-size:12.0pt;color:black'><o:p>&nbsp;</o:p></s=
pan></p></div><div><p class=3DMsoNormal><span style=3D'font-size:12.0pt;fon=
t-family:"Courier New";color:black'>&nbsp; &nbsp; &nbsp; &nbsp; public int =
AddShape(IShape shape)</span><span style=3D'font-size:12.0pt;color:black'><=
o:p></o:p></span></p></div><div><p class=3DMsoNormal><span style=3D'font-si=
ze:12.0pt;font-family:"Courier New";color:black'>&nbsp; &nbsp; &nbsp; &nbsp=
; {</span><span style=3D'font-size:12.0pt;color:black'><o:p></o:p></span></=
p></div><div><p class=3DMsoNormal><span style=3D'font-size:12.0pt;font-fami=
ly:"Courier New";color:black'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int=
 id =3D _nextId;</span><span style=3D'font-size:12.0pt;color:black'><o:p></=
o:p></span></p></div><div><p class=3DMsoNormal><span style=3D'font-size:12.=
0pt;font-family:"Courier New";color:black'>&nbsp; &nbsp; &nbsp; &nbsp; &nbs=
p; &nbsp; _shapes[id] =3D shape;</span><span style=3D'font-size:12.0pt;colo=
r:black'><o:p></o:p></span></p></div><div><p class=3DMsoNormal><span style=
=3D'font-size:12.0pt;font-family:"Courier New";color:black'>&nbsp; &nbsp; &=
nbsp; &nbsp; &nbsp; &nbsp; _nextId++;</span><span style=3D'font-size:12.0pt=
;color:black'><o:p></o:p></span></p></div><div><p class=3DMsoNormal><span s=
tyle=3D'font-size:12.0pt;font-family:"Courier New";color:black'>&nbsp; &nbs=
p; &nbsp; &nbsp; &nbsp; &nbsp; return id;</span><span style=3D'font-size:12=
.0pt;color:black'><o:p></o:p></span></p></div><div><p class=3DMsoNormal><sp=
an style=3D'font-size:12.0pt;font-family:"Courier New";color:black'>&nbsp; =
&nbsp; &nbsp; &nbsp; }</span><span style=3D'font-size:12.0pt;color:black'><=
o:p></o:p></span></p></div><div><p class=3DMsoNormal><span style=3D'font-si=
ze:12.0pt;color:black'><o:p>&nbsp;</o:p></span></p></div><div><p class=3DMs=
oNormal><span style=3D'font-size:12.0pt;font-family:"Courier New";color:bla=
ck'>&nbsp; &nbsp; &nbsp; &nbsp; public IShape GetShape(int id)</span><span =
style=3D'font-size:12.0pt;color:black'><o:p></o:p></span></p></div><div><p =
class=3DMsoNormal><span style=3D'font-size:12.0pt;font-family:"Courier New"=
;color:black'>&nbsp; &nbsp; &nbsp; &nbsp; {</span><span style=3D'font-size:=
12.0pt;color:black'><o:p></o:p></span></p></div><div><p class=3DMsoNormal><=
span style=3D'font-size:12.0pt;font-family:"Courier New";color:black'>&nbsp=
; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return _shapes[id];</span><span style=
=3D'font-size:12.0pt;color:black'><o:p></o:p></span></p></div><div><p class=
=3DMsoNormal><span style=3D'font-size:12.0pt;font-family:"Courier New";colo=
r:black'>&nbsp; &nbsp; &nbsp; &nbsp; }</span><span style=3D'font-size:12.0p=
t;color:black'><o:p></o:p></span></p></div><div><p class=3DMsoNormal><span =
style=3D'font-size:12.0pt;font-family:"Courier New";color:black'>&nbsp; &nb=
sp; }</span><span style=3D'font-size:12.0pt;color:black'><o:p></o:p></span>=
</p></div><div><p class=3DMsoNormal><span style=3D'font-size:12.0pt;font-fa=
mily:"Courier New";color:black'>}</span><span style=3D'font-size:12.0pt;col=
or:black'><o:p></o:p></span></p></div><p class=3DMsoNormal><span style=3D'f=
ont-size:12.0pt;color:black'><o:p>&nbsp;</o:p></span></p></div><div><p clas=
s=3DMsoNormal><span style=3D'font-size:12.0pt;color:black'><o:p>&nbsp;</o:p=
></span></p></div><div><p class=3DMsoNormal><span style=3D'font-size:12.0pt=
;color:black;background:#181A1B'>**** Python code ****</span><span style=3D=
'font-size:12.0pt;color:black'><o:p></o:p></span></p></div><div><p class=3D=
MsoNormal><span style=3D'font-size:12.0pt;font-family:"Courier New";color:b=
lack;background:#131516'>&gt;&gt;&gt; import clr</span><span style=3D'font-=
size:12.0pt;color:black'><o:p></o:p></span></p></div><div><p class=3DMsoNor=
mal><span style=3D'font-size:12.0pt;font-family:"Courier New";color:black;b=
ackground:#131516'>&gt;&gt;&gt; clr.AddReference(&quot;Example1&quot;)</spa=
n><span style=3D'font-size:12.0pt;color:black'><o:p></o:p></span></p></div>=
<div><p class=3DMsoNormal><span style=3D'font-size:12.0pt;font-family:"Cour=
ier New";color:black;background:#131516'>&gt;&gt;&gt; import Example1</span=
><span style=3D'font-size:12.0pt;color:black'><o:p></o:p></span></p></div><=
div><div><p class=3DMsoNormal><span style=3D'font-size:12.0pt;font-family:"=
Courier New";color:black;background:#131516'>&gt;&gt;&gt; sq1 =3D Example1.=
Square(2.)</span><span style=3D'font-size:12.0pt;color:black;background:#13=
1516'><o:p></o:p></span></p></div><div><p class=3DMsoNormal><span style=3D'=
font-size:12.0pt;font-family:"Courier New";color:black;background:#131516'>=
&gt;&gt;&gt; ci1 =3D Example1.Circle(1.3)</span><span style=3D'font-size:12=
.0pt;color:black;background:#131516'><o:p></o:p></span></p></div><div><p cl=
ass=3DMsoNormal><span style=3D'font-size:12.0pt;font-family:"Courier New";c=
olor:black;background:#131516'>&gt;&gt;&gt; sq2 =3D Example1.Square(2.5)</s=
pan><span style=3D'font-size:12.0pt;color:black;background:#131516'><o:p></=
o:p></span></p></div><div><p class=3DMsoNormal><span style=3D'font-size:12.=
0pt;font-family:"Courier New";color:black;background:#131516'>&gt;&gt;&gt; =
m =3D Example1.ShapeDataModel()</span><span style=3D'font-size:12.0pt;color=
:black;background:#131516'><o:p></o:p></span></p></div><div><p class=3DMsoN=
ormal><span style=3D'font-size:12.0pt;font-family:"Courier New";color:black=
;background:#131516'>&gt;&gt;&gt; m.AddShape(sq1)</span><span style=3D'font=
-size:12.0pt;color:black;background:#131516'><o:p></o:p></span></p></div><d=
iv><p class=3DMsoNormal><span style=3D'font-size:12.0pt;font-family:"Courie=
r New";color:black;background:#131516'>1</span><span style=3D'font-size:12.=
0pt;color:black;background:#131516'><o:p></o:p></span></p></div><div><p cla=
ss=3DMsoNormal><span style=3D'font-size:12.0pt;font-family:"Courier New";co=
lor:black;background:#131516'>&gt;&gt;&gt; m.AddShape(sq2)</span><span styl=
e=3D'font-size:12.0pt;color:black;background:#131516'><o:p></o:p></span></p=
></div><div><p class=3DMsoNormal><span style=3D'font-size:12.0pt;font-famil=
y:"Courier New";color:black;background:#131516'>2</span><span style=3D'font=
-size:12.0pt;color:black;background:#131516'><o:p></o:p></span></p></div><d=
iv><p class=3DMsoNormal><span style=3D'font-size:12.0pt;font-family:"Courie=
r New";color:black;background:#131516'>&gt;&gt;&gt; m.AddShape(ci1)</span><=
span style=3D'font-size:12.0pt;color:black;background:#131516'><o:p></o:p><=
/span></p></div><div><p class=3DMsoNormal><span style=3D'font-size:12.0pt;f=
ont-family:"Courier New";color:black;background:#131516'>3</span><span styl=
e=3D'font-size:12.0pt;color:black;background:#131516'><o:p></o:p></span></p=
></div><div><p class=3DMsoNormal><span style=3D'font-size:12.0pt;font-famil=
y:"Courier New";color:black;background:#131516'>&gt;&gt;&gt; m.GetShape(2)<=
/span><span style=3D'font-size:12.0pt;color:black;background:#131516'><o:p>=
</o:p></span></p></div><div><p class=3DMsoNormal><span style=3D'font-size:1=
2.0pt;font-family:"Courier New";color:black;background:#131516'>&lt;Example=
1.IShape object at 0x000002A3448A09A0&gt;</span><span style=3D'font-size:12=
.0pt;color:black;background:#131516'><o:p></o:p></span></p></div><div><p cl=
ass=3DMsoNormal><span style=3D'font-size:12.0pt;font-family:"Courier New";c=
olor:black;background:#131516'>&gt;&gt;&gt; m.GetShape(2).Area</span><span =
style=3D'font-size:12.0pt;color:black;background:#131516'><o:p></o:p></span=
></p></div><div><p class=3DMsoNormal><span style=3D'font-size:12.0pt;font-f=
amily:"Courier New";color:black;background:#131516'>6.25</span><span style=
=3D'font-size:12.0pt;color:black;background:#131516'><o:p></o:p></span></p>=
</div><div><p class=3DMsoNormal><span style=3D'font-size:12.0pt;font-family=
:"Courier New";color:black;background:#131516'>&gt;&gt;&gt; m.GetShape(2).L=
ength</span><span style=3D'font-size:12.0pt;color:black;background:#131516'=
><o:p></o:p></span></p></div><div><p class=3DMsoNormal><span style=3D'font-=
size:12.0pt;font-family:"Courier New";color:black;background:#131516'>Trace=
back (most recent call last):</span><span style=3D'font-size:12.0pt;color:b=
lack;background:#131516'><o:p></o:p></span></p></div><div><p class=3DMsoNor=
mal><span style=3D'font-size:12.0pt;font-family:"Courier New";color:#ED5C57=
;background:#131516'>&nbsp; File &quot;&lt;stdin&gt;&quot;, line 1, in &lt;=
module&gt;</span><span style=3D'font-size:12.0pt;color:black;background:#13=
1516'><o:p></o:p></span></p></div><div><p class=3DMsoNormal><span style=3D'=
font-size:12.0pt;font-family:"Courier New";color:#ED5C57;background:#131516=
'>AttributeError: 'IShape' object has no attribute 'Length'</span><span sty=
le=3D'font-size:12.0pt;color:black;background:#131516'><o:p></o:p></span></=
p></div></div><div><p class=3DMsoNormal><span style=3D'font-size:12.0pt;col=
or:black;background:#131516'><br><br></span><span style=3D'font-size:12.0pt=
;color:black'><o:p></o:p></span></p></div><div><p class=3DMsoNormal><span s=
tyle=3D'font-size:12.0pt;color:black;background:#131516'>**** summary ****<=
/span><span style=3D'font-size:12.0pt;color:black'><o:p></o:p></span></p></=
div><div><p class=3DMsoNormal><span style=3D'font-size:12.0pt;color:black;b=
ackground:#131516'>This factory and/or datamodel pattern is very common in =
my codebase and probably also lots of object oriented systems.&nbsp; The me=
ntioned PR breaks this common design pattern in C# objects wrapped by pytho=
nnet, and I would like a way to opt-out of it.&nbsp; Maybe an attribute on =
the method which returns an interface can be used, or maybe something globa=
l to switch this behavior.&nbsp; I think perhaps the original bug might als=
o have been fixed in a different way.&nbsp;</span><span style=3D'font-size:=
12.0pt;color:black'><o:p></o:p></span></p></div><div><p class=3DMsoNormal><=
span style=3D'font-size:12.0pt;color:black;background:#131516'><br><br></sp=
an><span style=3D'font-size:12.0pt;color:black'><o:p></o:p></span></p></div=
><p class=3DMsoNormal><span style=3D'font-size:12.0pt;color:black;backgroun=
d:#131516'>Thanks!<br>Mohamed</span><span style=3D'font-size:12.0pt;color:b=
lack'><o:p></o:p></span></p><p class=3DMsoNormal><o:p>&nbsp;</o:p></p></div=
></body></html>=

--===============8119071126935586326==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
PythonNet mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/pythonnet.python.org/
Member address: [email protected]

--===============8119071126935586326==--