@@ -5075,6 +5075,7 @@ def test_critical(self):
5075
5075
self .assertEqual (record .levelno , logging .CRITICAL )
5076
5076
self .assertEqual (record .msg , msg )
5077
5077
self .assertEqual (record .args , (self .recording ,))
5078
+ self .assertEqual (record .funcName , 'test_critical' )
5078
5079
5079
5080
def test_is_enabled_for (self ):
5080
5081
old_disable = self .adapter .logger .manager .disable
@@ -5093,15 +5094,9 @@ def test_has_handlers(self):
5093
5094
self .assertFalse (self .adapter .hasHandlers ())
5094
5095
5095
5096
def test_nested (self ):
5096
- class Adapter (logging .LoggerAdapter ):
5097
- prefix = 'Adapter'
5098
-
5099
- def process (self , msg , kwargs ):
5100
- return f"{ self .prefix } { msg } " , kwargs
5101
-
5102
5097
msg = 'Adapters can be nested, yo.'
5103
- adapter = Adapter (logger = self .logger , extra = None )
5104
- adapter_adapter = Adapter (logger = adapter , extra = None )
5098
+ adapter = PrefixAdapter (logger = self .logger , extra = None )
5099
+ adapter_adapter = PrefixAdapter (logger = adapter , extra = None )
5105
5100
adapter_adapter .prefix = 'AdapterAdapter'
5106
5101
self .assertEqual (repr (adapter ), repr (adapter_adapter ))
5107
5102
adapter_adapter .log (logging .CRITICAL , msg , self .recording )
@@ -5110,6 +5105,7 @@ def process(self, msg, kwargs):
5110
5105
self .assertEqual (record .levelno , logging .CRITICAL )
5111
5106
self .assertEqual (record .msg , f"Adapter AdapterAdapter { msg } " )
5112
5107
self .assertEqual (record .args , (self .recording ,))
5108
+ self .assertEqual (record .funcName , 'test_nested' )
5113
5109
orig_manager = adapter_adapter .manager
5114
5110
self .assertIs (adapter .manager , orig_manager )
5115
5111
self .assertIs (self .logger .manager , orig_manager )
@@ -5125,6 +5121,101 @@ def process(self, msg, kwargs):
5125
5121
self .assertIs (adapter .manager , orig_manager )
5126
5122
self .assertIs (self .logger .manager , orig_manager )
5127
5123
5124
+ def test_styled_adapter (self ):
5125
+ # Test an example from the Cookbook.
5126
+ records = self .recording .records
5127
+ adapter = StyleAdapter (self .logger )
5128
+ adapter .warning ('Hello, {}!' , 'world' )
5129
+ self .assertEqual (str (records [- 1 ].msg ), 'Hello, world!' )
5130
+ self .assertEqual (records [- 1 ].funcName , 'test_styled_adapter' )
5131
+ adapter .log (logging .WARNING , 'Goodbye {}.' , 'world' )
5132
+ self .assertEqual (str (records [- 1 ].msg ), 'Goodbye world.' )
5133
+ self .assertEqual (records [- 1 ].funcName , 'test_styled_adapter' )
5134
+
5135
+ def test_nested_styled_adapter (self ):
5136
+ records = self .recording .records
5137
+ adapter = PrefixAdapter (self .logger )
5138
+ adapter .prefix = '{}'
5139
+ adapter2 = StyleAdapter (adapter )
5140
+ adapter2 .warning ('Hello, {}!' , 'world' )
5141
+ self .assertEqual (str (records [- 1 ].msg ), '{} Hello, world!' )
5142
+ self .assertEqual (records [- 1 ].funcName , 'test_nested_styled_adapter' )
5143
+ adapter2 .log (logging .WARNING , 'Goodbye {}.' , 'world' )
5144
+ self .assertEqual (str (records [- 1 ].msg ), '{} Goodbye world.' )
5145
+ self .assertEqual (records [- 1 ].funcName , 'test_nested_styled_adapter' )
5146
+
5147
+ def test_find_caller_with_stacklevel (self ):
5148
+ the_level = 1
5149
+ trigger = self .adapter .warning
5150
+
5151
+ def innermost ():
5152
+ trigger ('test' , stacklevel = the_level )
5153
+
5154
+ def inner ():
5155
+ innermost ()
5156
+
5157
+ def outer ():
5158
+ inner ()
5159
+
5160
+ records = self .recording .records
5161
+ outer ()
5162
+ self .assertEqual (records [- 1 ].funcName , 'innermost' )
5163
+ lineno = records [- 1 ].lineno
5164
+ the_level += 1
5165
+ outer ()
5166
+ self .assertEqual (records [- 1 ].funcName , 'inner' )
5167
+ self .assertGreater (records [- 1 ].lineno , lineno )
5168
+ lineno = records [- 1 ].lineno
5169
+ the_level += 1
5170
+ outer ()
5171
+ self .assertEqual (records [- 1 ].funcName , 'outer' )
5172
+ self .assertGreater (records [- 1 ].lineno , lineno )
5173
+ lineno = records [- 1 ].lineno
5174
+ the_level += 1
5175
+ outer ()
5176
+ self .assertEqual (records [- 1 ].funcName , 'test_find_caller_with_stacklevel' )
5177
+ self .assertGreater (records [- 1 ].lineno , lineno )
5178
+
5179
+ def test_extra_in_records (self ):
5180
+ self .adapter = logging .LoggerAdapter (logger = self .logger ,
5181
+ extra = {'foo' : '1' })
5182
+
5183
+ self .adapter .critical ('foo should be here' )
5184
+ self .assertEqual (len (self .recording .records ), 1 )
5185
+ record = self .recording .records [0 ]
5186
+ self .assertTrue (hasattr (record , 'foo' ))
5187
+ self .assertEqual (record .foo , '1' )
5188
+
5189
+ def test_extra_not_merged_by_default (self ):
5190
+ self .adapter .critical ('foo should NOT be here' , extra = {'foo' : 'nope' })
5191
+ self .assertEqual (len (self .recording .records ), 1 )
5192
+ record = self .recording .records [0 ]
5193
+ self .assertFalse (hasattr (record , 'foo' ))
5194
+
5195
+
5196
+ class PrefixAdapter (logging .LoggerAdapter ):
5197
+ prefix = 'Adapter'
5198
+
5199
+ def process (self , msg , kwargs ):
5200
+ return f"{ self .prefix } { msg } " , kwargs
5201
+
5202
+
5203
+ class Message :
5204
+ def __init__ (self , fmt , args ):
5205
+ self .fmt = fmt
5206
+ self .args = args
5207
+
5208
+ def __str__ (self ):
5209
+ return self .fmt .format (* self .args )
5210
+
5211
+
5212
+ class StyleAdapter (logging .LoggerAdapter ):
5213
+ def log (self , level , msg , / , * args , stacklevel = 1 , ** kwargs ):
5214
+ if self .isEnabledFor (level ):
5215
+ msg , kwargs = self .process (msg , kwargs )
5216
+ self .logger .log (level , Message (msg , args ), ** kwargs ,
5217
+ stacklevel = stacklevel + 1 )
5218
+
5128
5219
5129
5220
class LoggerTest (BaseTest , AssertErrorMessage ):
5130
5221
0 commit comments