@@ -242,36 +242,48 @@ module Stdlib {
242242 // logging
243243 // ---------------------------------------------------------------------------
244244 /**
245- * Provides models for the `logging.Logger` class and subclasses.
245+ * Provides models for the `logging.Logger` class
246246 *
247247 * See https://docs.python.org/3.9/library/logging.html#logging.Logger.
248248 */
249249 module Logger {
250+ /** Gets a reference to the `logging.Logger` class or any subclass. */
251+ private API:: Node subclassRef ( ) {
252+ result = API:: moduleImport ( "logging" ) .getMember ( "Logger" ) .getASubclass * ( )
253+ }
254+
250255 /**
251- * An instance of `logging.Logger`. Extend this class to model new instances.
252- * Most major frameworks will provide a logger instance as a class attribute.
256+ * A source of instances of `logging.Logger`, extend this class to model new instances.
257+ *
258+ * This can include instantiations of the class, return values from function
259+ * calls, or a special parameter that will be set when functions are called by an external
260+ * library.
261+ *
262+ * Use the predicate `Logger::instance()` to get references to instances of `logging.Logger`.
253263 */
254- abstract class LoggerInstance extends API:: Node {
255- override string toString ( ) { result = "logger" }
256- }
264+ abstract class InstanceSource extends DataFlow:: LocalSourceNode { }
257265
258- /** Gets a reference to the `logging.Logger` class or any subclass. */
259- API:: Node subclassRef ( ) {
260- result = API:: moduleImport ( "logging" ) .getMember ( "Logger" ) .getASubclass * ( )
266+ /** A direct instantiation of `logging.Logger`. */
267+ private class ClassInstantiation extends InstanceSource , DataFlow:: CallCfgNode {
268+ ClassInstantiation ( ) {
269+ this = subclassRef ( ) .getACall ( )
270+ or
271+ this = API:: moduleImport ( "logging" ) .getMember ( "root" ) .getAnImmediateUse ( )
272+ or
273+ this = API:: moduleImport ( "logging" ) .getMember ( "getLogger" ) .getACall ( )
274+ }
261275 }
262276
263- /** Gets a reference to an instance of `logging.Logger` or any subclass. */
264- API:: Node instance ( ) {
265- result instanceof LoggerInstance
266- or
267- result = subclassRef ( ) .getReturn ( )
268- or
269- result = API:: moduleImport ( "logging" )
270- or
271- result = API:: moduleImport ( "logging" ) .getMember ( "root" )
277+ /** Gets a reference to an instance of `logging.Logger`. */
278+ private DataFlow:: TypeTrackingNode instance ( DataFlow:: TypeTracker t ) {
279+ t .start ( ) and
280+ result instanceof InstanceSource
272281 or
273- result = API :: moduleImport ( "logging" ) . getMember ( "getLogger" ) . getReturn ( )
282+ exists ( DataFlow :: TypeTracker t2 | result = instance ( t2 ) . track ( t2 , t ) )
274283 }
284+
285+ /** Gets a reference to an instance of `logging.Logger`. */
286+ DataFlow:: Node instance ( ) { instance ( DataFlow:: TypeTracker:: end ( ) ) .flowsTo ( result ) }
275287 }
276288}
277289
@@ -2698,7 +2710,9 @@ private module StdlibPrivate {
26982710 method = "log" and
26992711 msgIndex = 1
27002712 |
2701- this = Stdlib:: Logger:: instance ( ) .getMember ( method ) .getACall ( )
2713+ this .( DataFlow:: MethodCallNode ) .calls ( Stdlib:: Logger:: instance ( ) , method )
2714+ or
2715+ this = API:: moduleImport ( "logging" ) .getMember ( method ) .getACall ( )
27022716 )
27032717 }
27042718
0 commit comments