8000 Added supporr for class/property/method attributes. · pythonnet/pythonnet@28f4717 · GitHub
[go: up one dir, main page]

Skip to content

Commit 28f4717

Browse files
committed
Added supporr for class/property/method attributes.
- Added shortened Attribute aliases which just generates tuples. - More general CLR base class support - creating a class instance from C# is now more similar to creating one from python. - Added attribute decorator to clr.py. - Added testing for the various possibilities
1 parent 65c2c00 commit 28f4717

File tree

6 files changed

+454
-16
lines changed

6 files changed

+454
-16
lines changed

src/python_tests_runner/PythonTestRunner.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ static IEnumerable<string[]> PythonTestCases()
3939
yield return new[] { "test_delegate", "test_bool_delegate" };
4040
yield return new[] { "test_subclass", "test_virtual_generic_method" };
4141
yield return new[] { "test_subclass", "test_interface_and_class_impl2" };
42+
yield return new[] { "test_subclass", "test_class_with_attributes" };
43+
yield return new[] { "test_subclass", "test_class_with_advanced_attribute" };
44+
yield return new[] { "test_subclass", "test_more_subclasses" };
4245
}
4346

4447
/// <summary>

src/runtime/Resources/clr.py

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,18 @@ def test(self):
2121
string z = x.test; // calls into python and returns "x"
2222
"""
2323

24-
def __init__(self, type_, fget=None, fset=None):
24+
def __init__(self, type_, fget=None, fset=None, attributes = []):
2525
self.__name__ = getattr(fget, "__name__", None)
2626
self._clr_property_type_ = type_
2727
self.fget = fget
2828
self.fset = fset
29-
29+
self._clr_attributes_ = attributes
3030
def __call__(self, fget):
31-
return self.__class__(self._clr_property_type_,
31+
self.__class__(self._clr_property_type_,
3232
fget=fget,
33-
fset=self.fset)
33+
fset=self.fset,
34+
attributes = self._clr_attributes_)
35+
3436

3537
def setter(self, fset):
3638
self.fset = fset
@@ -47,8 +49,32 @@ def __set__(self, instance, value):
4749
if not self.fset:
4850
raise AttributeError("%s is read-only" % self.__name__)
4951
return self.fset.__get__(instance, None)(value)
52+
def add_attribute(self, attribute):
53+
self._clr_attributes_.append(attribute)
54+
return self
5055

56+
class property(object):
5157

58+
def __init__(self, type, default):
59+
import weakref
60+
self._clr_property_type_ = type
61+
self.default = default
62+
self.values = weakref.WeakKeyDictionary()
63+
self._clr_attributes_ = []
64+
self.fget = 1
65+
self.fset = 1
66+
def __get__(self, instance, owner):
67+
v = self.values.get(instance, self.default)
68+
return v
69+
def __set__(self, instance, value):
70+
self.values[instance] = value
71+
def add_attribute(self, attribute):
72+
self._clr_attributes_.append(attribute)
73+
return self
74+
def __call__(self, type, default):
75+
self2 = self.__class__(self._clr_property_type_, type, default)
76+
self2._clr_attributes_ = self._clr_attributes_
77+
return self2
5278
class clrmethod(object):
5379
"""
5480
Method decorator for exposing python methods to .NET.
@@ -67,18 +93,47 @@ def test(self, x):
6793
int z = x.test("hello"); // calls into python and returns len("hello")
6894
"""
6995

70-
def __init__(self, return_type, arg_types, clrname=None, func=None):
96+
def __init__(self, return_type = None, arg_types = [], clrname=None, func=None, **kwargs):
97+
if return_type == None:
98+
import System
99+
return_type = System.Void
71100
self.__name__ = getattr(func, "__name__", None)
72101
self._clr_return_type_ = return_type
73102
self._clr_arg_types_ = arg_types
74103
self._clr_method_name_ = clrname or self.__name__
75104
self.__func = func
105+
if 'attributes' in kwargs:
106+
self._clr_attributes_ = kwargs["attributes"]
107+
else:
108+
self._clr_attributes_ = []
76109

77110
def __call__(self, func):
78-
return self.__class__(self._clr_return_type_,
111+
self2 = self.__class__(self._clr_return_type_,
79112
self._clr_arg_types_,
80113
clrname=self._clr_method_name_,
81114
func=func)
115+
self2._clr_attributes_ = self._clr_attributes_
116+
return self2
82117

83118
def __get__(self, instance, owner):
84119
return self.__func.__get__(instance, owner)
120+
121+
def clr_attribute(self, attribute):
122+
self._clr_attributes_.append(attribute)
123+
return self
124+
125+
class attribute(object):
126+
127+
def __init__(self, attr, *args, **kwargs):
128+
self.attr = attr
129+
import Python.Runtime
130+
#todo: ensure that attributes only are pushed when @ is used.
131+
#import inspect
132+
#Python.Runtime.PythonDerivedType.Test(inspect.stack()[1].code_context)
133+
134+
Python.Runtime.PythonDerivedType.PushAttribute(attr)
135+
def __call__(self, x):
136+
import Python.Runtime
137+
if Python.Runtime.PythonDerivedType.AssocAttribute(self.attr, x):
138+
pass
139+
return x

0 commit comments

Comments
 (0)
0