Package: accrocchio
accrocchioAccrocchio is a library to mark and being notified of smelly code
(a.k.a, “accrocchio”).Examplefromaccrocchio.badgeofshameimportaccrocchiofromaccrocchioimportobserversclassAClassThatSmells(metaclass=accrocchio):pass@accrocchiodefa_function_that_smells():passaccrocchio.how_many()# here we have 1, as you have declared a smelly classAClassThatSmells()accrocchio.how_many()# here we have 2, as you have created an instance of a smelly classa_function_that_smells()accrocchio.how_many()# here we have 3, as you have invoked a smelly functionaccrocchio.reset()accrocchio.how_many()# here we have 0# You can also be notified of smelly code execution, such as:classMyAccrocchioObserver(observers.AccrocchioObserver):defon_accrocchio(self):print('Another accrocchio!')defreset(self):print('Reset accrocchi')accrocchio.add_observer(MyAccrocchioObserver())a_function_that_smells()# prints 'Another accrocchio!'accrocchio.reset()# prints 'Reset accrocchi'It is also possible to decorate the entire class. Both the declaration
and the instantiation of such classes increase the accrocchio counters.fromaccrocchio.badgeofshameimportaccrocchiofromaccrocchioimportobservers@accrocchioclassAClassThatSmells:passaccrocchio.how_many()# here we have 1, as you have declared a smelly classAClassThatSmells()accrocchio.how_many()# here we have 2, as you have created an instance of a smelly classYou might declare an accrocchio using type hinting, as follows:fromaccrocchio.badgeofshameimportaccrocchio,detonatordeff(a:detonator[int]):passaccrocchio.how_many()# here we have 1, as you have declared a smelly parameterdetonator.how_many()# here we have 1, as you have declared a smelly parameterf(1)accrocchio.how_many()# here we still have 1detonator.how_many()# here we still have 1The library also implementsMichael Duell’s resign
patterns.fromaccrocchio.badgeofshameimportaccrocchio,detonator@accrocchiodefaccrocchio_fun():pass@detonatordefdetonator_fun():passaccrocchio_fun()accrocchio.how_many()# here we have 1, as you have invoked an accrocchio functiondetonator.how_many()# here we have 0, as you have never invoked a detonator functiondetonator_fun()detonator.how_many()# here we have 1, as you have invoked a detonator functionaccrocchio.how_many()# here we have 2, as you have invoked a detonator function, which is an accrocchioYou may mark arbitrary code as an accrocchio:fromaccrocchio.badgeofshameimportdetonator,epoxy,this_is_a,this_is_anthis_is_an(epoxy)this_is_a(detonator)detonator.how_many()# this will be 1epoxy.how_many()# this will be 1If you need to have to mark a specific portion of your code as an
accrocchio, you can use it as a context manager, as follows:fromaccrocchio.badgeofshameimportdetonator,epoxywithdetonator:...withepoxy:...detonator.how_many()# this will be 1epoxy.how_many()# this will be 1For a full list of the implemented accrocchio resign patterns, please
consultMichael Duell’s resign
patterns.Some final notes:This library is useful only if a small part of the software is an
accrocchioWe intentionally left out Python versions before 3.5, as we think
they are a complete accrocchio.We intentionally did not pass the accrocchio to the ‘on_accrocchio’
observer function, as you should treat all the accrocchioes the same
wayThe plural for accrocchio is accrocchioesIf you are using this library, you are deliberately brutalizing The
Zen of Python; thus it has been replaced with a more appropriate one.
Just doimport thisafterimport accrocchio.