obsolete (or in some
deprecated languages) attribute or decorator is a useful tool for a library to signal to its consumers that part of it’s API has been deprecated.
Using it on internal—owned by the same team—code for a project should be avoided.
Marking something as obsolete will generate a compiler warning (in a statically checked language at any rate), and committing code into trunk that generates warnings should be avoided. We only have two options with warnings: dealing with them, or ignoring them. Tolerating warnings is an instance of tolerating entropy in the code base.
If a piece of code is not yet removed from the project it’s not yet obsolete, even if there is a better alternative available. We want to encourage active ownership of the cleanup code problems, rather than a passive hope that everyone else will do the job.
This becomes challenging when the aspirationally obsolete code is pervasive and will take a long time to remove—maybe there are reasons why untangling it from an older piece of code will be difficult. How do you indicate to your colleagues that the old version should not be used without throwing a lot of new warnings into the product?
Create tickets in the job tracker, and get buy in from the team to commit to eliminating the problem code piece by piece. No new warnings are introduced, the old code is actively being addressed.
For larger teams, this can be supported by marking the code as obsolete, but annotate all the existing call-sites with a pragma to ignore that specific warning. This way, any new usages would become warnings, but existing usages would not. As a bonus, the process of adding these pragmas may be impetus to address lingering easy cases.