From c04b615a07a7fcd128fbe5b420bc68b6b3d4ab41 Mon Sep 17 00:00:00 2001 From: Taus Date: Mon, 23 Feb 2026 15:55:58 +0000 Subject: [PATCH] Python: Extend DuckTyping module Adds `overridesMethod` and `isPropertyAccessor`. --- .../new/internal/DataFlowDispatch.qll | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll index 2aaa33de159..529e90798ba 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll @@ -2111,4 +2111,27 @@ module DuckTyping { ) ) } + + /** + * Gets the `__init__` function that will be invoked when `cls` is constructed, + * resolved according to the MRO. + */ + Function getInit(Class cls) { result = invokedFunctionFromClassConstruction(cls, "__init__") } + + /** + * Holds if `f` overrides a method in a superclass with the same name. + */ + predicate overridesMethod(Function f) { + exists(Class cls | f.getScope() = cls | hasMethod(getADirectSuperclass(cls), f.getName())) + } + + /** + * Holds if `f` is a property accessor (decorated with `@property`, `@name.setter`, + * or `@name.deleter`). + */ + predicate isPropertyAccessor(Function f) { + exists(Attribute a | a = f.getADecorator() | a.getName() = "setter" or a.getName() = "deleter") + or + f.getADecorator().(Name).getId() = "property" + } }