[Python.NET] Re: Wrap in interface (#1240)
Victor “LOST” Milovanov <[email protected]> Mon, 8 Feb 2021 10:56:30 -0800
| Newsgroups | gmane.comp.python.dotnet |
|---|---|
| Message-ID | <[email protected]> |
--===============8220023346847500867==
Content-Type: multipart/related;
boundary="_6CCED182-84FA-4A6B-B89F-23DF5A87480D_"
--_6CCED182-84FA-4A6B-B89F-23DF5A87480D_
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset="utf-8"
<html xmlns:v=3D"urn:schemas-microsoft-com:vml" xmlns:o=3D"urn:schemas-micr=
osoft-com:office:office" xmlns:w=3D"urn:schemas-microsoft-com:office:word" =
xmlns:m=3D"http://schemas.microsoft.com/office/2004/12/omml" xmlns=3D"http:=
//www.w3.org/TR/REC-html40"><head><meta http-equiv=3DContent-Type content=
=3D"text/html; charset=3Dutf-8"><meta name=3DGenerator content=3D"Microsoft=
Word 15 (filtered medium)"><!--[if !mso]><style>v\:* {behavior:url(#defaul=
t#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style><![endif]--><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;}
p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
{mso-style-priority:34;
margin-top:0in;
margin-right:0in;
margin-bottom:0in;
margin-left:.5in;
font-size:11.0pt;
font-family:"Calibri",sans-serif;}
p.xmsonormal, li.xmsonormal, div.xmsonormal
{mso-style-name:x_msonormal;
margin:0in;
font-size:11.0pt;
font-family:"Calibri",sans-serif;}
.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;}
/* List Definitions */
@list l0
{mso-list-id:1392969730;
mso-list-type:hybrid;
mso-list-template-ids:-406285992 -1 67698713 67698715 67698703 67698713 67=
698715 67698703 67698713 67698715;}
@list l0:level1
{mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level2
{mso-level-number-format:alpha-lower;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level3
{mso-level-number-format:roman-lower;
mso-level-tab-stop:none;
mso-level-number-position:right;
text-indent:-9.0pt;}
@list l0:level4
{mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level5
{mso-level-number-format:alpha-lower;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level6
{mso-level-number-format:roman-lower;
mso-level-tab-stop:none;
mso-level-number-position:right;
text-indent:-9.0pt;}
@list l0:level7
{mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level8
{mso-level-number-format:alpha-lower;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level9
{mso-level-number-format:roman-lower;
mso-level-tab-stop:none;
mso-level-number-position:right;
text-indent:-9.0pt;}
ol
{margin-bottom:0in;}
ul
{margin-bottom:0in;}
--></style></head><body lang=3DEN-US link=3Dblue vlink=3D"#954F72" style=3D=
'word-wrap:break-word'><div class=3DWordSection1><p class=3DMsoNormal>A dum=
p of thoughts on the matter:</p><p class=3DMsoNormal><o:p> </o:p></p><=
ol style=3D'margin-top:0in' start=3D1 type=3D1><li class=3DMsoListParagraph=
style=3D'margin-left:0in;mso-list:l0 level1 lfo1'>IronPython is Python 2 o=
nly, Python.NET 3.0+ is Python 3 only. Why not use 2.5.x until you are comf=
ortable to change API?</li><li class=3DMsoListParagraph style=3D'margin-lef=
t:0in;mso-list:l0 level1 lfo1'>Flag is possible, but I would not recommend =
that approach, because it makes combining multiple libraries that use diffe=
rent global flags problematic.</li><li class=3DMsoListParagraph style=3D'ma=
rgin-left:0in;mso-list:l0 level1 lfo1'>Perhaps we could allow codecs to han=
dle instances of wrapped interfaces (actually, isn=E2=80=99t that currently=
allowed?)</li><li class=3DMsoListParagraph style=3D'margin-left:0in;mso-li=
st:l0 level1 lfo1'>IronPython apparently allows explicit interface implemen=
tations to be called (instead of returning interface-wrapped instances), if=
there=E2=80=99s no conflict with regular methods. Perhaps we should consid=
er this as an option.</li><li class=3DMsoListParagraph style=3D'margin-left=
:0in;mso-list:l0 level1 lfo1'>Alternatively, we can keep wrapped instances,=
but allow to resolve public members too if the method is not found in the =
interface. I like this option better than 4, because actual type of an elem=
ent in ISomething[] won=E2=80=99t change behavior of invoking interface mem=
ber. It might still affect `hasattr`, but this is somewhat expected.</li></=
ol><p class=3DMsoNormal><o:p> </o:p></p><p class=3DMsoNormal>Regards,<=
/p><p class=3DMsoNormal>Victor</p><p class=3DMsoNormal><o:p> </o:p></p=
><div style=3D'mso-element:para-border-div;border:none;border-top:solid #E1=
E1E1 1.0pt;padding:3.0pt 0in 0in 0in'><p class=3DMsoNormal style=3D'border:=
none;padding:0in'><b>From: </b><a href=3D"mailto:[email protected]">=
Mohamed Koubaa</a><br><b>Sent: </b>Monday, February 8, 2021 8:34 AM<br><b>T=
o: </b><a href=3D"mailto:[email protected]">A list for users and develop=
ers of Python.NET</a><br><b>Subject: </b>[Python.NET] Re: Wrap in interface=
(#1240)</p></div><p class=3DMsoNormal><o:p> </o:p></p><div><p class=
=3DMsoNormal><span style=3D'font-size:12.0pt;color:black'>Victor,<o:p></o:p=
></span></p></div><div><p class=3DMsoNormal><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'>Sorry for the late response.&nb=
sp; I think what I would need is some kind of flag in the python runtime to=
choose the old behavior (without having to have my own branch). Of c=
ourse there is a workaround but we've invested a lot of time in designing t=
he API for both CPython & IronPython and it would be ideal if they did =
not differ in this way. <o:p></o:p></span></p></div><div><p clas=
s=3DMsoNormal><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'>This could be a global flag on the runtime and/or an attribut=
e on a class/interface to decide on a granular level whether the specific c=
lass/interface will use interface method binding or instance method binding=
.<o:p></o:p></span></p></div><div><p class=3DMsoNormal><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'>Thoughts?<o:p></o:p>=
</span></p></div><div><p class=3DMsoNormal><span style=3D'font-size:12.0pt;=
color:black'><o:p> </o:p></span></p></div><div><p class=3DMsoNormal><s=
pan style=3D'font-size:12.0pt;color:black'>Thanks!<o:p></o:p></span></p></d=
iv><div><p class=3DMsoNormal><span style=3D'font-size:12.0pt;color:black'>M=
ohamed<o:p></o:p></span></p></div><p class=3DMsoNormal><img border=3D0 widt=
h=3D694 height=3D2 style=3D'width:7.2291in;height:.0208in' id=3D"Horizontal=
_x0020_Line_x0020_1" src=3D"cid:image001.png-CFHuyTl/[email protected]"><o:p></o:p>=
</p><div id=3DdivRplyFwdMsg><p class=3DMsoNormal><b><span style=3D'color:bl=
ack'>From:</span></b><span style=3D'color:black'> Victor =E2=80=9CLOST=E2=
=80=9D Milovanov <[email protected]><br><b>Sent:</b> Monday, Nove=
mber 2, 2020 8:35 PM<br><b>To:</b> A list for users and developers of Pytho=
n.NET <[email protected]><br><b>Subject:</b> [Python.NET] Re: Wrap=
in interface (#1240)</span> <o:p></o:p></p><div><p class=3DMsoNormal> =
;<o:p></o:p></p></div></div><div><div style=3D'border:solid #9C6500 1.0pt;p=
adding:2.0pt 2.0pt 2.0pt 2.0pt'><p style=3D'line-height:12.0pt;background:#=
FFEB9C'><b><span style=3D'font-size:10.0pt;color:red'>[External Sender]</sp=
an></b></p></div><div><div><p class=3Dxmsonormal>The original bug report de=
scribed a similar problem, except the behavior without defaulting to strict=
er interface types is very unintuitive. Imagine you have a well documented =
library, that exposes property <b>Prop</b> of type <b>IInterface</b>. When =
specific class implements some <b>Method</b> in <b>IInterface</b> exp=
licitly (which arguably is a very minor implementation detail), and you cal=
l <b>Prop.Method()</b> in Python, it can fail with AttributeError despite t=
he documentation claiming this method exists on the interface. This is very=
confusing. IMHO, more confusing, than inability to get Length of an elemen=
t of <b>IShape[]</b>.</p><p class=3Dxmsonormal> </p><p class=3Dxmsonor=
mal>We could try to improve the situation for Python folks by allowing inte=
rface instance wrappers to fall back to the original class instance in case=
the attribute is not found in the interface itself. I think this might sti=
ll be problematic, as it would make the behavior of hasattr and other simil=
ar functions a bit surprising.</p><p class=3Dxmsonormal> </p><p class=
=3Dxmsonormal>Regardless, there=E2=80=99s a workaround for the scenario you=
described which is just doing <b>m.GetShape(1).__raw_implementation__.Leng=
th </b>or </p><p class=3Dxmsonormal><b>m.GetShape(1).__implementation__.Len=
gth </b>depending if you need an encoded instance.</p><p class=3Dxmsonormal=
> </p><p class=3Dxmsonormal>Regards,</p><p class=3Dxmsonormal>Victor M=
ilovanov</p><p class=3Dxmsonormal> </p><div style=3D'border:none;borde=
r-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in 0in 0in'><p class=3Dxmsonormal>=
<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>Subject: </b>[P=
ython.NET] Wrap in interface (#1240)</p></div><p class=3Dxmsonormal> <=
/p><div><p class=3Dxmsonormal><span style=3D'font-size:12.0pt;color:black'>=
Hello,</span></p></div><div><p class=3Dxmsonormal><span style=3D'font-size:=
12.0pt;color:black'> </span></p></div><div><p class=3Dxmsonormal><span=
style=3D'font-size:12.0pt;color:black'>This <a href=3D"https://nam10.safel=
inks.protection.outlook.com/?url=3Dhttps%3A%2F%2Fgithub.com%2Fpythonnet%2Fp=
ythonnet%2Fpull%2F1240&data=3D04%7C01%7Cmohamed.koubaa%40ansys.com%7C37=
b0dd3831f140993f6008d87fa1418f%7C34c6ce6715b84eff80e952da8be89706%7C0%7C0%7=
C637399677854765584%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2l=
uMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=3DtTftofPt0a7ds4g1qBjL=
IBXi7iFOgtygMW3Xa3WHF%2Fo%3D&reserved=3D0" title=3D"https://github.com/=
pythonnet/pythonnet/pull/1240">PR</a> changed behavior of pythonnet to=
use stricter typing when a method returns an interface. I'd like a w=
ay to opt-out of this behavior, and I'll share a representative use-case be=
low. The tl;dr is that python is a dynamic language and I expect the =
C# objects which pythonnet wraps to behave more like "dynamic" an=
d less like the static types on the interface.</span></p></div><div><p clas=
s=3Dxmsonormal><span style=3D'font-size:12.0pt;color:black'> </span></=
p></div><div><p class=3Dxmsonormal><span style=3D'font-size:12.0pt;color:bl=
ack'>**** C# code ****</span></p></div><div><p class=3Dxmsonormal><span sty=
le=3D'font-size:12.0pt;font-family:"Courier New";color:black'>namespace Exa=
mple1</span><span style=3D'font-size:12.0pt;color:black'> </span></p><div><=
p class=3Dxmsonormal><span style=3D'font-size:12.0pt;font-family:"Courier N=
ew";color:black'>{</span></p></div><div><p class=3Dxmsonormal><span style=
=3D'font-size:12.0pt;font-family:"Courier New";color:black'> p=
ublic enum ShapeType</span></p></div><div><p class=3Dxmsonormal><span style=
=3D'font-size:12.0pt;font-family:"Courier New";color:black'> {=
</span></p></div><div><p class=3Dxmsonormal><span style=3D'font-size:12.0pt=
;font-family:"Courier New";color:black'> Square,=
</span></p></div><div><p class=3Dxmsonormal><span style=3D'font-size:12.0pt=
;font-family:"Courier New";color:black'> Circle<=
/span></p></div><div><p class=3Dxmsonormal><span style=3D'font-size:12.0pt;=
font-family:"Courier New";color:black'> }</span></p></div><div=
><p class=3Dxmsonormal><span style=3D'font-size:12.0pt;font-family:"Courier=
New";color:black'> public interface IShape</span></p></div><d=
iv><p class=3Dxmsonormal><span style=3D'font-size:12.0pt;font-family:"Couri=
er New";color:black'> {</span></p></div><div><p class=3Dxmsono=
rmal><span style=3D'font-size:12.0pt;font-family:"Courier New";color:black'=
> void Draw();</span></p></div><div><p class=3Dx=
msonormal><span style=3D'font-size:12.0pt;color:black'> </span></p></d=
iv><div><p class=3Dxmsonormal><span style=3D'font-size:12.0pt;font-family:"=
Courier New";color:black'> double Area { get; }<=
/span></p></div><div><p class=3Dxmsonormal><span style=3D'font-size:12.0pt;=
color:black'> </span></p></div><div><p class=3Dxmsonormal><span style=
=3D'font-size:12.0pt;font-family:"Courier New";color:black'> &=
nbsp; ShapeType Type { get; }</span></p></div><div><p class=3Dxmsono=
rmal><span style=3D'font-size:12.0pt;font-family:"Courier New";color:black'=
> }</span></p></div><div><p class=3Dxmsonormal><span style=3D'=
font-size:12.0pt;color:black'> </span></p></div><div><p class=3Dxmsono=
rmal><span style=3D'font-size:12.0pt;font-family:"Courier New";color:black'=
> public class Square : IShape</span></p></div><div><p class=
=3Dxmsonormal><span style=3D'font-size:12.0pt;font-family:"Courier New";col=
or:black'> {</span></p></div><div><p class=3Dxmsonormal><span =
style=3D'font-size:12.0pt;font-family:"Courier New";color:black'> &nb=
sp; public double Length { get; }</span></p></div><div><p cla=
ss=3Dxmsonormal><span style=3D'font-size:12.0pt;font-family:"Courier New";c=
olor:black'> public Square(double length)</span>=
</p></div><div><p class=3Dxmsonormal><span style=3D'font-size:12.0pt;font-f=
amily:"Courier New";color:black'> {</span></p></=
div><div><p class=3Dxmsonormal><span style=3D'font-size:12.0pt;font-family:=
"Courier New";color:black'> Length=
=3D length;</span></p></div><div><p class=3Dxmsonormal><span style=3D'font=
-size:12.0pt;font-family:"Courier New";color:black'> &n=
bsp; }</span></p></div><div><p class=3Dxmsonormal><span style=3D'font-size:=
12.0pt;color:black'> </span></p></div><div><p class=3Dxmsonormal><span=
style=3D'font-size:12.0pt;font-family:"Courier New";color:black'> &n=
bsp; public void Draw() {}</span></p></div><div><p class=3Dxm=
sonormal><span style=3D'font-size:12.0pt;font-family:"Courier New";color:bl=
ack'> public double Area { get { return Length *=
Length; } }</span></p></div><div><p class=3Dxmsonormal><span style=3D'font=
-size:12.0pt;font-family:"Courier New";color:black'> &n=
bsp; public ShapeType Type { get { return ShapeType.Square; } }</span></p><=
/div><div><p class=3Dxmsonormal><span style=3D'font-size:12.0pt;font-family=
:"Courier New";color:black'> }</span></p></div><div><p class=
=3Dxmsonormal><span style=3D'font-size:12.0pt;color:black'> </span></p=
></div><div><p class=3Dxmsonormal><span style=3D'font-size:12.0pt;font-fami=
ly:"Courier New";color:black'> public class Circle : IShape</s=
pan></p></div><div><p class=3Dxmsonormal><span style=3D'font-size:12.0pt;fo=
nt-family:"Courier New";color:black'> {</span></p></div><div><=
p class=3Dxmsonormal><span style=3D'font-size:12.0pt;font-family:"Courier N=
ew";color:black'> public double Radius { get; }<=
/span></p></div><div><p class=3Dxmsonormal><span style=3D'font-size:12.0pt;=
font-family:"Courier New";color:black'> public C=
ircle(double radius)</span></p></div><div><p class=3Dxmsonormal><span style=
=3D'font-size:12.0pt;font-family:"Courier New";color:black'> &=
nbsp; {</span></p></div><div><p class=3Dxmsonormal><span style=3D'fo=
nt-size:12.0pt;font-family:"Courier New";color:black'> =
Radius =3D radius;</span></p></div><div><p class=3Dxms=
onormal><span style=3D'font-size:12.0pt;font-family:"Courier New";color:bla=
ck'> }</span></p></div><div><p class=3Dxmsonorma=
l><span style=3D'font-size:12.0pt;color:black'> </span></p></div><div>=
<p class=3Dxmsonormal><span style=3D'font-size:12.0pt;font-family:"Courier =
New";color:black'> public void Draw() {}</span><=
/p></div><div><p class=3Dxmsonormal><span style=3D'font-size:12.0pt;font-fa=
mily:"Courier New";color:black'> public double A=
rea { get { return Math.PI * Radius * Radius; } }</span></p></div><div><p c=
lass=3Dxmsonormal><span style=3D'font-size:12.0pt;font-family:"Courier New"=
;color:black'> public ShapeType Type { get { ret=
urn ShapeType.Circle; } }</span></p></div><div><p class=3Dxmsonormal><span =
style=3D'font-size:12.0pt;font-family:"Courier New";color:black'> &nb=
sp; }</span></p></div><div><p class=3Dxmsonormal><span style=3D'font-size:1=
2.0pt;color:black'> </span></p></div><div><p class=3Dxmsonormal><span =
style=3D'font-size:12.0pt;font-family:"Courier New";color:black'> &nb=
sp; public class ShapeDataModel</span></p></div><div><p class=3Dxmsonormal>=
<span style=3D'font-size:12.0pt;font-family:"Courier New";color:black'>&nbs=
p; {</span></p></div><div><p class=3Dxmsonormal><span style=3D'font-=
size:12.0pt;font-family:"Courier New";color:black'> &nb=
sp; private Dictionary<int, IShape> _shapes =3D new Dictionary<int=
, IShape>();</span></p></div><div><p class=3Dxmsonormal><span style=3D'f=
ont-size:12.0pt;font-family:"Courier New";color:black'> =
private int _nextId =3D 1;</span></p></div><div><p class=3Dxmsonorm=
al><span style=3D'font-size:12.0pt;color:black'> </span></p></div><div=
><p class=3Dxmsonormal><span style=3D'font-size:12.0pt;font-family:"Courier=
New";color:black'> public int AddShape(IShape s=
hape)</span></p></div><div><p class=3Dxmsonormal><span style=3D'font-size:1=
2.0pt;font-family:"Courier New";color:black'> {<=
/span></p></div><div><p class=3Dxmsonormal><span style=3D'font-size:12.0pt;=
font-family:"Courier New";color:black'> &=
nbsp; int id =3D _nextId;</span></p></div><div><p class=3Dxmsonormal><span =
style=3D'font-size:12.0pt;font-family:"Courier New";color:black'> &nb=
sp; _shapes[id] =3D shape;</span></p></div><div=
><p class=3Dxmsonormal><span style=3D'font-size:12.0pt;font-family:"Courier=
New";color:black'> _nextId++;</sp=
an></p></div><div><p class=3Dxmsonormal><span style=3D'font-size:12.0pt;fon=
t-family:"Courier New";color:black'> &nbs=
p; return id;</span></p></div><div><p class=3Dxmsonormal><span style=3D'fon=
t-size:12.0pt;font-family:"Courier New";color:black'> &=
nbsp; }</span></p></div><div><p class=3Dxmsonormal><span style=3D'font-size=
:12.0pt;color:black'> </span></p></div><div><p class=3Dxmsonormal><spa=
n style=3D'font-size:12.0pt;font-family:"Courier New";color:black'> &=
nbsp; public IShape GetShape(int id)</span></p></div><div><p =
class=3Dxmsonormal><span style=3D'font-size:12.0pt;font-family:"Courier New=
";color:black'> {</span></p></div><div><p class=
=3Dxmsonormal><span style=3D'font-size:12.0pt;font-family:"Courier New";col=
or:black'> return _shapes[id];</sp=
an></p></div><div><p class=3Dxmsonormal><span style=3D'font-size:12.0pt;fon=
t-family:"Courier New";color:black'> }</span></p=
></div><div><p class=3Dxmsonormal><span style=3D'font-size:12.0pt;font-fami=
ly:"Courier New";color:black'> }</span></p></div><div><p class=
=3Dxmsonormal><span style=3D'font-size:12.0pt;font-family:"Courier New";col=
or:black'>}</span></p></div><p class=3Dxmsonormal><span style=3D'font-size:=
12.0pt;color:black'> </span></p></div><div><p class=3Dxmsonormal><span=
style=3D'font-size:12.0pt;color:black'> </span></p></div><div><p clas=
s=3Dxmsonormal><span style=3D'font-size:12.0pt;color:black;background:#181A=
1B'>**** Python code ****</span></p></div><div><p class=3Dxmsonormal><span =
style=3D'font-size:12.0pt;font-family:"Courier New";color:black;background:=
#131516'>>>> import clr</span></p></div><div><p class=3Dxmsonormal=
><span style=3D'font-size:12.0pt;font-family:"Courier New";color:black;back=
ground:#131516'>>>> clr.AddReference("Example1")</span><=
/p></div><div><p class=3Dxmsonormal><span style=3D'font-size:12.0pt;font-fa=
mily:"Courier New";color:black;background:#131516'>>>> import Exam=
ple1</span></p></div><div><div><p class=3Dxmsonormal><span style=3D'font-si=
ze:12.0pt;font-family:"Courier New";color:black;background:#131516'>>>=
;> sq1 =3D Example1.Square(2.)</span></p></div><div><p class=3Dxmsonorma=
l><span style=3D'font-size:12.0pt;font-family:"Courier New";color:black;bac=
kground:#131516'>>>> ci1 =3D Example1.Circle(1.3)</span></p></div>=
<div><p class=3Dxmsonormal><span style=3D'font-size:12.0pt;font-family:"Cou=
rier New";color:black;background:#131516'>>>> sq2 =3D Example1.Squ=
are(2.5)</span></p></div><div><p class=3Dxmsonormal><span style=3D'font-siz=
e:12.0pt;font-family:"Courier New";color:black;background:#131516'>>>=
> m =3D Example1.ShapeDataModel()</span></p></div><div><p class=3Dxmsono=
rmal><span style=3D'font-size:12.0pt;font-family:"Courier New";color:black;=
background:#131516'>>>> m.AddShape(sq1)</span></p></div><div><p cl=
ass=3Dxmsonormal><span style=3D'font-size:12.0pt;font-family:"Courier New";=
color:black;background:#131516'>1</span></p></div><div><p class=3Dxmsonorma=
l><span style=3D'font-size:12.0pt;font-family:"Courier New";color:black;bac=
kground:#131516'>>>> m.AddShape(sq2)</span></p></div><div><p class=
=3Dxmsonormal><span style=3D'font-size:12.0pt;font-family:"Courier New";col=
or:black;background:#131516'>2</span></p></div><div><p class=3Dxmsonormal><=
span style=3D'font-size:12.0pt;font-family:"Courier New";color:black;backgr=
ound:#131516'>>>> m.AddShape(ci1)</span></p></div><div><p class=3D=
xmsonormal><span style=3D'font-size:12.0pt;font-family:"Courier New";color:=
black;background:#131516'>3</span></p></div><div><p class=3Dxmsonormal><spa=
n style=3D'font-size:12.0pt;font-family:"Courier New";color:black;backgroun=
d:#131516'>>>> m.GetShape(2)</span></p></div><div><p class=3Dxmson=
ormal><span style=3D'font-size:12.0pt;font-family:"Courier New";color:black=
;background:#131516'><Example1.IShape object at 0x000002A3448A09A0></=
span></p></div><div><p class=3Dxmsonormal><span style=3D'font-size:12.0pt;f=
ont-family:"Courier New";color:black;background:#131516'>>>> m.Get=
Shape(2).Area</span></p></div><div><p class=3Dxmsonormal><span style=3D'fon=
t-size:12.0pt;font-family:"Courier New";color:black;background:#131516'>6.2=
5</span></p></div><div><p class=3Dxmsonormal><span style=3D'font-size:12.0p=
t;font-family:"Courier New";color:black;background:#131516'>>>> m.=
GetShape(2).Length</span></p></div><div><p class=3Dxmsonormal><span style=
=3D'font-size:12.0pt;font-family:"Courier New";color:black;background:#1315=
16'>Traceback (most recent call last):</span></p></div><div><p class=3Dxmso=
normal><span style=3D'font-size:12.0pt;font-family:"Courier New";color:#ED5=
C57;background:#131516'> File "<stdin>", line 1, in &=
lt;module></span></p></div><div><p class=3Dxmsonormal><span style=3D'fon=
t-size:12.0pt;font-family:"Courier New";color:#ED5C57;background:#131516'>A=
ttributeError: 'IShape' object has no attribute 'Length'</span></p></div></=
div><div><p class=3Dxmsonormal style=3D'margin-bottom:12.0pt'><o:p> </=
o:p></p></div><div><p class=3Dxmsonormal><span style=3D'font-size:12.0pt;co=
lor:black;background:#131516'>**** summary ****</span></p></div><div><p cla=
ss=3Dxmsonormal><span style=3D'font-size:12.0pt;color:black;background:#131=
516'>This factory and/or datamodel pattern is very common in my codebase an=
d probably also lots of object oriented systems. The mentioned PR bre=
aks this common design pattern in C# objects wrapped by pythonnet, and I wo=
uld like a way to opt-out of it. Maybe an attribute on the method whi=
ch returns an interface can be used, or maybe something global to switch th=
is behavior. I think perhaps the original bug might also have been fi=
xed in a different way. </span></p></div><div><p class=3Dxmsonormal st=
yle=3D'margin-bottom:12.0pt'><o:p> </o:p></p></div><p class=3Dxmsonorm=
al><span style=3D'font-size:12.0pt;color:black;background:#131516'>Thanks!<=
br>Mohamed</span></p></div></div></div><p class=3Dxmsonormal> </p><p c=
lass=3DMsoNormal><o:p> </o:p></p></div></body></html>=
--_6CCED182-84FA-4A6B-B89F-23DF5A87480D_
Content-Type: image/png; name="C081996CDAA945DBACD618306EE5771E.png"
Content-ID: <image001.png-CFHuyTl/[email protected]>
Content-Transfer-Encoding: base64
Content-Disposition: inline; filename="C081996CDAA945DBACD618306EE5771E.png"
iVBORw0KGgoAAAANSUhEUgAAArYAAAACCAYAAACtx5+mAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAlSURBVFhH7cMBDQAABAAw/UtJIIEw5GD/9gAA
gBeyelRV9faeBRsQNwwY9nKzAAAAAElFTkSuQmCC
--_6CCED182-84FA-4A6B-B89F-23DF5A87480D_--
--===============8220023346847500867==
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]
--===============8220023346847500867==--