@@ -136,6 +136,51 @@ def v2(self, _, __):
136136
137137 assert _AndValidator ((v , v2 )) == a ._validator
138138
139+ def test_converter_decorator_single (self ):
140+ """
141+ If _CountingAttr.converter is used as a decorator and there is no
142+ decorator set, the decorated method is used as the converter.
143+ """
144+ a = attr .ib ()
145+
146+ @a .converter
147+ def v (self , value , field ):
148+ pass
149+
150+ decorated_converter = attr .Converter (
151+ lambda value , _self , field : v (_self , field , value ),
152+ takes_self = True ,
153+ takes_field = True ,
154+ )
155+
156+ assert decorated_converter == a ._converter
157+
158+ @pytest .mark .parametrize (
159+ "wrap" , [lambda v : v , lambda v : [v ], attr .converters .pipe ]
160+ )
161+ def test_converter_decorator (self , wrap ):
162+ """
163+ If _CountingAttr.converter is used as a decorator and there is already
164+ a decorator set, the decorators are composed using `pipe`.
165+ """
166+
167+ def v (_ ):
168+ pass
169+
170+ a = attr .ib (converter = wrap (v ))
171+
172+ @a .converter
173+ def v2 (self , value , field ):
174+ pass
175+
176+ decorated_converter = attr .Converter (
177+ lambda value , _self , field : v2 (_self , field , value ),
178+ takes_self = True ,
179+ takes_field = True ,
180+ )
181+
182+ assert attr .converters .pipe ((v , decorated_converter )) == a ._converter
183+
139184 def test_default_decorator_already_set (self ):
140185 """
141186 Raise DefaultAlreadySetError if the decorator is used after a default
0 commit comments