What’s New (releases 0.3.2, 0.3.1 and 0.3.0)¶
This release, 0.3.2, updates log_calls for Python 3.6. There are no
changes to package code, only minor changes to documentation and to a single test.
However, the package itself is reorganized: the docs/
and tests/
subdirectories
have been moved to the top level of the distribution archive, at the same level
as log_calls/
rather than within the package. They are no longer installed
by setup.py
or pip
, so you’ll need the distribution to access their files.
This chapter catalogs additions and changes in the current release and its predecessor. Those in 0.3.2/0.3.1 are few; those in 0.3.0, several. Appendix II contains the complete list of what has been new in earlier versions.
Version 0.3.2 / 0.3.1¶
What’s New¶
This version simplifies writing debugging messages and dumping expressions to the log_calls output stream in a log_calls-aware way. There are now two methods for these purposes:
log_calls.print()
log_calls.print_exprs()
which can be called from within any decorated callable. These supercede the now deprecated
log_message
andlog_exprs
attributes on each decorated callable. The new methods are notably easier to use from within classes.Like their predecessors, these methods are indent-aware, and, unlike the global
print
function, they produce no output unless called from within an enabled decorated function.You can now simply call
log_calls.print('Starting timer.')
orlog_calls.print_exprs('x', 'y', '(x+y)/2'
, without having to first obtain a reference to a “wrapper” and then calling thelog_*
methods on that.Version 0.3.0 provided one-stop shopping for obtaining wrappers; in earlier versions of log_calls you had to navigate to it yourself, with different expressions for instance methods, classmethods, staticmethods and properties.
By default, if you call
log_calls.print*
from within a method or function that isn’t decorated, it does nothing. You can comment out the@log_calls
decorator, or use theNO_DECO
parameter to achieve the same end, and the.print*
method calls will play nicely: they won’t output anything, and the calls won’t raiseAttributeError
as they would formerly when calling the methods on a wrapper thatis None
. In short, leaving thelog_calls.print*
lines uncommented is as benign as it can be.But probably at some point you do want to know when you have lingering code that’s supposedly development-only. log_calls will inform you of that if you set the following new global flag to
True
(or to something truthy):log_calls.print_methods_raise_if_no_deco
(bool
; default:False
)When this flag is true, calls to
log_calls.print
andlog_calls.print_exprs
from within an undecorated function or method will raise an appropriate exception. This compels you to comment out or delete any calls tolog_calls.print*
from within undecorated functions or methods.
The chapter Writing log_calls-Aware Debug Messages documents the new methods and global flag.
The new methods and global exist on
record_history
too:record_history.print()
record_history.print_exprs()
record_history.print_methods_raise_if_no_deco
all exist and behave analogously to the log_calls attributes.
What’s Changed¶
A callable’s display name now has its
__name__
in parentheses following its__qualname__
if (and only if)- the
name
parameter was not provided to log_calls for the callable, and - the callable’s
__name__
is not a substring of its__qualname__
.
See the section section Decorating “external” code in the Quick Start chapter for a motivating example.
- the
log_exprs
now asuffix
keyword parameter (as doeslog_calls.print_exprs()
).Fixed:
log_calls.decorate_module()
wouldn’t decorate only classes, or only functions; it would decorate nothing instead.
Deprecations¶
wrapper.
log_message()
and wrapper.log_exprs()
.Use
log_calls.print()
andlog_calls.print_exprs()
instead.
Version 0.3.0¶
What Was New in 0.3.0¶
log_calls and record_history can decorate classes – all, or some, of the methods and properties within a class – and their inner classes.
The decorators properly decorate instance methods, classmethods, staticmethods and properties (whether defined with the
@property
decorator or theproperty
function).Settings provided in the class-level decorator apply to all decorated members and inner classes. Members and inner classes can also be individually decorated, and (by default) their explicitly given settings supplement and override those given at outer levels.
omit
andonly
keyword parameters to a class decorator let you concisely specify which callables to decorate. Each is a sequence of strings specifying methods and/or properties — by name, with optional class prefixes, with optional suffixes for selecting specific property methods, as well as with wildcards and character-range inclusion and exclusion using “glob” syntax.A decorated class has methods
get_log_calls_wrapper(methodname)
andget_own_log_calls_wrapper()
, the latter for use by methods and properties of the decorated class. These provide easy and uniform ways to obtain the wrapper of a decorated method, without the special-case handling otherwise (and formerly) required for classmethods and properties.record_history provides the analogous methods
get_record_history_wrapper(methodname)
andget_own_record_history_wrapper()
.
log_calls and record_history have classmethods to programmatically decorate functions, classes and class hierarchies, even modules, for situations where altering source code is impractical (too many things to decorate) or inadvisable (third-party packages and modules). These methods can expedite learning a new codebase:
decorate_class(baseclass, decorate_subclasses=False, **setting_kwds)
decorates a class and optionally all of its subclassesdecorate_hierarchy(baseclass, **setting_kwds)
decorates a class and all of its subclassesdecorate_function(f, **setting_kwds)
decorates a function defined in or imported into the module from which you call this methoddecorate_package_function(f, **setting_kwds)
decorates a function in an imported packagedecorate_module_function(f, **setting_kwds)
decorates a function in an imported package or moduledecorate_module(mod: 'module', functions=True, classes=True, **setting_kwds)
decorates all functions and classes in a module.
log_calls has classmethods to globally set and reset default values for settings, program-wide:
set_defaults(new_default_settings=None, **more_defaults)
reset_defaults()
as well as classmethods to retrieve the current defaults and the “factory defaults”, each as an
OrderedDict
:get_defaults_OD()
get_factory_defaults_OD()
The
log_exprs()
method, added as an attribute to decorated callables, allows a wrapped callable to easily “dump” values of variables and expressions. Simply pass it one or more expressions, as strings; it prints the expressions together with their current values. See Writing expressions and their values with log_calls.print_exprs().New keyword parameters:
NO_DECO
, a “kill switch”. When true, the decorator does nothing, returning the decorated callable or class itself, unwrapped and unaltered. Using this parameter in a settings file or dictionary lets you toggle “true bypass” with a single switch, e.g. for production, without having to comment out every decoration.name
, a literal string or a format string, lets you specify a custom name for a decorated callable.override
, a boolean, intended mainly for use with log_calls as a functional and with thedecorate_*
methods, allows updating the explicit settings of already decorated classes and callables.mute
, a three-valued setting:- mute nothing (default)
- mute output about calls but allow
log_message()
andlog_exprs()
output - mute everything.
Global mute,
log_calls.mute
, which can assume the same values as the newmute
setting.Classmethods
log_calls.version()
andrecord_history.version()
return the version string.
What Changed in 0.3.0¶
- The
indent
setting is now by defaultTrue
. - By default, the display name for a function or method is now its
__qualname__
, which in the case of methods includes class name. This makes unnecessary what was probably the main use case ofprefix
. - record_history can now use
log_message()
andlog_exprs()
. Output is always viaprint
. - Fixed:
log_message()
formerly would blow up if called on a function or method for which logging was disabled. It now produces no output in that situation. prefix
is mutable in log_calls and record_history.- Fixed, addressed: double-decoration no longer raises an exception. Doing so doesn’t wrap another decorator around an already wrapped function or method, but merely adjusts the settings of the decorated callable.
- Change to
__repr__
handling in thearguments
section of output: useobject.__repr__
for objects still in construction (i.e. whose__init__
methods are still active), otherwise userepr
. - log_calls won’t itself decorate
__repr__
methods (it will decorate them instead withreprlib.recursive_repr()
); record_history can decorate__repr__
. - Removed the deprecated
settings_path
keyword parameter. - Officially, explicitly requires Python 3.3+. The package won’t install on earlier versions.
- For consistency with the
get*_defaults_OD()
methods, theas_OrderedDict()
method of the “settings” objects (e.g.log_calls_settings
) has been renamedas_OD()
. Note,as_OrderedDict()
is still supported but is now deprecated. You’ll have to run the Python interpreter with the-Wd
flag to see the deprecation warning(s), which include the file names and line numbers whereas_OrderedDict()
occurs. (Since Python 3.2, DeprecationWarnings are by default not displayed.)