2
2
3
3
4
4
import copy
5
+ import warnings
5
6
6
7
from ._compat import PY_3_9_PLUS , get_generic_base
7
8
from ._make import NOTHING , _obj_setattr , fields
@@ -331,8 +332,6 @@ def assoc(inst, **changes):
331
332
This function will not be removed du to the slightly different approach
332
333
compared to `attrs.evolve`.
333
334
"""
334
- import warnings
335
-
336
335
warnings .warn (
337
336
"assoc is deprecated and will be removed after 2018/01." ,
338
337
DeprecationWarning ,
@@ -350,9 +349,10 @@ def assoc(inst, **changes):
350
349
return new
351
350
352
351
353
- def evolve (inst , ** changes ):
352
+ def evolve (* args , ** changes ):
354
353
"""
355
- Create a new instance, based on *inst* with *changes* applied.
354
+ Create a new instance, based on the first positional argument with
355
+ *changes* applied.
356
356
357
357
:param inst: Instance of a class with *attrs* attributes.
358
358
:param changes: Keyword changes in the new copy.
@@ -364,8 +364,26 @@ def evolve(inst, **changes):
364
364
:raise attrs.exceptions.NotAnAttrsClassError: If *cls* is not an *attrs*
365
365
class.
366
366
367
- .. versionadded:: 17.1.0
367
+ .. versionadded:: 17.1.0
368
+ .. deprecated:: 23.1.0
369
+ It is now deprecated to pass the instance using the keyword argument
370
+ *inst*. It will raise a warning until at least April 2024, after which
371
+ it will become an error. Always pass the instance as a positional
372
+ argument.
368
373
"""
374
+ # Try to get instance by positional argument first.
375
+ # Use changes otherwise and warn it'll break.
376
+ if args :
377
+ (inst ,) = args
378
+ else :
379
+ warnings .warn (
380
+ "Passing the instance per keyword argument is deprecated and "
381
+ "will stop working in, or after, April 2024." ,
382
+ DeprecationWarning ,
383
+ stacklevel = 2 ,
384
+ )
385
+ inst = changes .pop ("inst" )
386
+
369
387
cls = inst .__class__
370
388
attrs = fields (cls )
371
389
for a in attrs :
0 commit comments