From 94267755283d5cddfb1ce6618f76e277eeefef68 Mon Sep 17 00:00:00 2001 From: Dor-bl <59066376+Dor-bl@users.noreply.github.com> Date: Sun, 25 Oct 2026 21:46:08 +0000 Subject: [PATCH] perf: optimize extract_const_attributes traversal Reorder filter conditions in extract_const_attributes to check attr.isupper() first, short-circuiting non-uppercase attributes. In addition, check callable(value) and isinstance(value, classmethod) directly on the unpacked dictionary values rather than issuing repeated getattr(cls, attr) calls on the class. --- appium/common/helper.py | 6 ++++- test/unit/common/helper_test.py | 42 +++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 test/unit/common/helper_test.py diff --git a/appium/common/helper.py b/appium/common/helper.py index 821b7c9f..d963dfb8 100644 --- a/appium/common/helper.py +++ b/appium/common/helper.py @@ -27,7 +27,11 @@ def extract_const_attributes(cls: type) -> dict[str, Any]: Returns: dict with constants attributes and values in the class """ - return {attr: value for attr, value in vars(cls).items() if not callable(getattr(cls, attr)) and attr.isupper()} + return { + attr: value + for attr, value in vars(cls).items() + if attr.isupper() and not callable(value) and not isinstance(value, classmethod) + } def library_version() -> str: diff --git a/test/unit/common/helper_test.py b/test/unit/common/helper_test.py new file mode 100644 index 00000000..088a2721 --- /dev/null +++ b/test/unit/common/helper_test.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from appium.common.helper import extract_const_attributes + + +class DummyConstants: + VAL1 = 100 + VAL2 = 'test_value' + _PRIVATE = 'private_const' + lower_case = 'ignored' + + @classmethod + def CLASS_METHOD(cls): + pass + + @staticmethod + def STATIC_METHOD(): + pass + + def instance_method(self): + pass + + +def test_extract_const_attributes(): + constants = extract_const_attributes(DummyConstants) + assert constants == { + 'VAL1': 100, + 'VAL2': 'test_value', + '_PRIVATE': 'private_const', + }