From f3781ba4ac13c4255407299db770d5f0c6ed800a Mon Sep 17 00:00:00 2001 From: narrieta Date: Fri, 23 Feb 2024 16:22:51 -0800 Subject: [PATCH 1/4] Run pylint on Python 3.11 --- .github/workflows/ci_pr.yml | 51 ++++++++++++++++-------- azurelinuxagent/common/utils/textutil.py | 3 +- azurelinuxagent/ga/cgroupconfigurator.py | 9 +++-- ci/2.7.pylintrc | 42 ------------------- ci/3.6.pylintrc | 40 ------------------- ci/{3.10.pylintrc => pylintrc} | 1 - tests/common/test_event.py | 4 +- tests/common/test_singletonperthread.py | 8 ++-- tests/ga/test_multi_config_extension.py | 24 +++++------ tests/ga/test_remoteaccess_handler.py | 5 +-- tests/lib/tools.py | 4 +- 11 files changed, 63 insertions(+), 128 deletions(-) delete mode 100644 ci/2.7.pylintrc delete mode 100644 ci/3.6.pylintrc rename ci/{3.10.pylintrc => pylintrc} (98%) diff --git a/.github/workflows/ci_pr.yml b/.github/workflows/ci_pr.yml index 153d5392f..b6d27d066 100644 --- a/.github/workflows/ci_pr.yml +++ b/.github/workflows/ci_pr.yml @@ -9,7 +9,7 @@ on: jobs: test-python-2_6-and-3_4-versions: - + strategy: fail-fast: false matrix: @@ -87,32 +87,19 @@ jobs: matrix: include: - python-version: "3.5" - PYLINTOPTS: "--rcfile=ci/3.6.pylintrc --ignore=tests_e2e,makepkg.py" - - python-version: "3.6" - PYLINTOPTS: "--rcfile=ci/3.6.pylintrc --ignore=tests_e2e" - - python-version: "3.7" - PYLINTOPTS: "--rcfile=ci/3.6.pylintrc --ignore=tests_e2e" - - python-version: "3.8" - PYLINTOPTS: "--rcfile=ci/3.6.pylintrc --ignore=tests_e2e" - - python-version: "3.9" - PYLINTOPTS: "--rcfile=ci/3.6.pylintrc" additional-nose-opts: "--with-coverage --cover-erase --cover-inclusive --cover-branches --cover-package=azurelinuxagent" - - python-version: "3.10" - PYLINTOPTS: "--rcfile=ci/3.10.pylintrc --ignore=tests" + - python-version: "3.11" name: "Python ${{ matrix.python-version }} Unit Tests" runs-on: ubuntu-20.04 env: - PYLINTOPTS: ${{ matrix.PYLINTOPTS }} - PYLINTFILES: "azurelinuxagent setup.py makepkg.py tests tests_e2e" NOSEOPTS: "--with-timer ${{ matrix.additional-nose-opts }}" - PYTHON_VERSION: ${{ matrix.python-version }} steps: @@ -130,13 +117,43 @@ jobs: sudo env "PATH=$PATH" python -m pip install --upgrade pip sudo env "PATH=$PATH" pip install -r requirements.txt sudo env "PATH=$PATH" pip install -r test-requirements.txt + sudo env "PATH=$PATH" pip install --upgrade pylint - name: Run pylint run: | - pylint $PYLINTOPTS --jobs=0 $PYLINTFILES + # + # List of files/directories to be checked by pylint. + # The end-to-end tests run only on Python 3.9 and we lint them only on that version. + # + PYLINT_FILES="azurelinuxagent setup.py makepkg.py tests" + if [[ "${{ matrix.python-version }}" == "3.9" ]]; then + PYLINT_FILES="$PYLINT_FILES tests_e2e" + fi + + # + # Command-line options for pylint. + # * "unused-private-member" is not implemented on 3.5 and will produce "E0012: Bad option value 'unused-private-member' (bad-option-value)" + # so we suppress "bad-option-value". + # * 3.9 will produce "no-member" for several properties/methods that are added to the mocks used by the unit tests (e.g + # "E1101: Instance of 'WireProtocol' has no 'aggregate_status' member") so we add them as generated members. + # * 'no-self-use' ("R0201: Method could be a function") was moved to an optional extension on 3.9 and is no longer used by default. It needs + # to be suppressed for previous versions (3.0-3.8), though. + # + PYLINT_OPTIONS="--rcfile=ci/pylintrc --jobs=0" + if [[ "${{ matrix.python-version }}" == "3.5" ]]; then + PYLINT_OPTIONS="$PYLINT_OPTIONS --disable=bad-option-value" + fi + if [[ "${{ matrix.python-version }}" == "3.9" ]]; then + PYLINT_OPTIONS="$PYLINT_OPTIONS --generated-member=WireProtocol.aggregate_status,WireProtocol.incarnation,UpdateHandler._fail_gs_count,UpdateHandler._protocol" + fi + if [[ "${{ matrix.python-version }}" =~ ^3\.[0-8]$ ]]; then + PYLINT_OPTIONS="$PYLINT_OPTIONS --disable=no-self-use" + fi + + pylint $PYLINT_OPTIONS $PYLINT_FILES - name: Test with nosetests - if: matrix.python-version != '3.10' && (success() || (failure() && steps.install-dependencies.outcome == 'success')) + if: contains(fromJSON('["3.10", "3.11"]'), matrix.python-version) == false && (success() || (failure() && steps.install-dependencies.outcome == 'success')) run: | ./ci/nosetests.sh exit $? diff --git a/azurelinuxagent/common/utils/textutil.py b/azurelinuxagent/common/utils/textutil.py index 1ff7a7e91..9e857274d 100644 --- a/azurelinuxagent/common/utils/textutil.py +++ b/azurelinuxagent/common/utils/textutil.py @@ -17,7 +17,8 @@ # Requires Python 2.6+ and Openssl 1.0+ import base64 -import crypt +# W4901: Deprecated module 'crypt' (deprecated-module) +import crypt # pylint: disable=deprecated-module import hashlib import random import re diff --git a/azurelinuxagent/ga/cgroupconfigurator.py b/azurelinuxagent/ga/cgroupconfigurator.py index fa4dbe202..09eb8b55a 100644 --- a/azurelinuxagent/ga/cgroupconfigurator.py +++ b/azurelinuxagent/ga/cgroupconfigurator.py @@ -350,8 +350,9 @@ def __reload_systemd_config(): except Exception as exception: _log_cgroup_warning("daemon-reload failed (create azure slice): {0}", ustr(exception)) + # W0238: Unused private member `_Impl.__create_unit_file(path, contents)` (unused-private-member) @staticmethod - def __create_unit_file(path, contents): + def __create_unit_file(path, contents): # pylint: disable=unused-private-member parent, _ = os.path.split(path) if not os.path.exists(parent): fileutil.mkdir(parent, mode=0o755) @@ -359,8 +360,9 @@ def __create_unit_file(path, contents): fileutil.write_file(path, contents) _log_cgroup_info("{0} {1}", "Updated" if exists else "Created", path) + # W0238: Unused private member `_Impl.__cleanup_unit_file(path)` (unused-private-member) @staticmethod - def __cleanup_unit_file(path): + def __cleanup_unit_file(path): # pylint: disable=unused-private-member if os.path.exists(path): try: os.remove(path) @@ -522,8 +524,9 @@ def __reset_agent_cpu_quota(): _log_cgroup_info('CPUQuota: {0}', systemd.get_unit_property(systemd.get_agent_unit_name(), "CPUQuotaPerSecUSec")) + # W0238: Unused private member `_Impl.__try_set_cpu_quota(quota)` (unused-private-member) @staticmethod - def __try_set_cpu_quota(quota): + def __try_set_cpu_quota(quota): # pylint: disable=unused-private-member try: drop_in_file = os.path.join(systemd.get_agent_drop_in_path(), _DROP_IN_FILE_CPU_QUOTA) contents = _DROP_IN_FILE_CPU_QUOTA_CONTENTS_FORMAT.format(quota) diff --git a/ci/2.7.pylintrc b/ci/2.7.pylintrc deleted file mode 100644 index 0cba65ee9..000000000 --- a/ci/2.7.pylintrc +++ /dev/null @@ -1,42 +0,0 @@ -# python2.7 uses pylint 1.9.5, whose docs can be found here: http://pylint.pycqa.org/en/1.9/technical_reference/features.html#messages -# python3.4 uses pylint 2.3.1, whose docs can be found here: http://pylint.pycqa.org/en/pylint-2.3.1/technical_reference/features.html - -[MESSAGES CONTROL] - -disable=C, # (C) convention, for programming standard violation - consider-using-dict-comprehension, # (R1717): *Consider using a dictionary comprehension* - consider-using-in, # (R1714): *Consider merging these comparisons with "in" to %r* - consider-using-set-comprehension, # (R1718): *Consider using a set comprehension* - consider-using-with, # (R1732): *Emitted if a resource-allocating assignment or call may be replaced by a 'with' block* - duplicate-code, # (R0801): *Similar lines in %s files* - no-init, # (W0232): Class has no __init__ method - no-else-break, # (R1723): *Unnecessary "%s" after "break"* - no-else-continue, # (R1724): *Unnecessary "%s" after "continue"* - no-else-raise, # (R1720): *Unnecessary "%s" after "raise"* - no-else-return, # (R1705): *Unnecessary "%s" after "return"* - no-self-use, # (R0201): *Method could be a function* - protected-access, # (W0212): Access to a protected member of a client class - simplifiable-if-expression, # (R1719): *The if expression can be replaced with %s* - simplifiable-if-statement, # (R1703): *The if statement can be replaced with %s* - super-with-arguments, # (R1725): *Consider using Python 3 style super() without arguments* - too-few-public-methods, # (R0903): *Too few public methods (%s/%s)* - too-many-ancestors, # (R0901): *Too many ancestors (%s/%s)* - too-many-arguments, # (R0913): *Too many arguments (%s/%s)* - too-many-boolean-expressions, # (R0916): *Too many boolean expressions in if statement (%s/%s)* - too-many-branches, # (R0912): *Too many branches (%s/%s)* - too-many-instance-attributes, # (R0902): *Too many instance attributes (%s/%s)* - too-many-locals, # (R0914): *Too many local variables (%s/%s)* - too-many-nested-blocks, # (R1702): *Too many nested blocks (%s/%s)* - too-many-public-methods, # (R0904): *Too many public methods (%s/%s)* - too-many-return-statements, # (R0911): *Too many return statements (%s/%s)* - too-many-statements, # (R0915): *Too many statements (%s/%s)* - useless-object-inheritance, # (R0205): *Class %r inherits from object, can be safely removed from bases in python3* - useless-return, # (R1711): *Useless return at end of function or method* - bad-continuation, # Buggy, **REMOVED in pylint-2.6.0** - bad-option-value, # pylint does not recognize the error code/symbol (needed to supress breaking changes across pylint versions) - bad-whitespace, # Used when a wrong number of spaces is used around an operator, bracket or block opener. - broad-except, # Used when an except catches a too general exception, possibly burying unrelated errors. - deprecated-lambda, # Used when a lambda is the first argument to “map” or “filter”. It could be clearer as a list comprehension or generator expression. (2.7 only) - missing-docstring, # Used when a module, function, class or method has no docstring - old-style-class, # Used when a class is defined that does not inherit from another class and does not inherit explicitly from “object”. (2.7 only) - fixme, # Used when a warning note as FIXME or TODO is detected diff --git a/ci/3.6.pylintrc b/ci/3.6.pylintrc deleted file mode 100644 index fcbae9383..000000000 --- a/ci/3.6.pylintrc +++ /dev/null @@ -1,40 +0,0 @@ -# python 3.6+ uses the latest pylint version, whose docs can be found here: http://pylint.pycqa.org/en/stable/technical_reference/features.html - -[MESSAGES CONTROL] - -disable=C, # (C) convention, for programming standard violation - broad-except, # (W0703): *Catching too general exception %s* - consider-using-dict-comprehension, # (R1717): *Consider using a dictionary comprehension* - consider-using-in, # (R1714): *Consider merging these comparisons with "in" to %r* - consider-using-set-comprehension, # (R1718): *Consider using a set comprehension* - consider-using-with, # (R1732): *Emitted if a resource-allocating assignment or call may be replaced by a 'with' block* - duplicate-code, # (R0801): *Similar lines in %s files* - fixme, # Used when a warning note as FIXME or TODO is detected - no-else-break, # (R1723): *Unnecessary "%s" after "break"* - no-else-continue, # (R1724): *Unnecessary "%s" after "continue"* - no-else-raise, # (R1720): *Unnecessary "%s" after "raise"* - no-else-return, # (R1705): *Unnecessary "%s" after "return"* - no-init, # (W0232): Class has no __init__ method - no-self-use, # (R0201): *Method could be a function* - protected-access, # (W0212): Access to a protected member of a client class - raise-missing-from, # (W0707): *Consider explicitly re-raising using the 'from' keyword* - redundant-u-string-prefix, # The u prefix for strings is no longer necessary in Python >=3.0 - simplifiable-if-expression, # (R1719): *The if expression can be replaced with %s* - simplifiable-if-statement, # (R1703): *The if statement can be replaced with %s* - super-with-arguments, # (R1725): *Consider using Python 3 style super() without arguments* - too-few-public-methods, # (R0903): *Too few public methods (%s/%s)* - too-many-ancestors, # (R0901): *Too many ancestors (%s/%s)* - too-many-arguments, # (R0913): *Too many arguments (%s/%s)* - too-many-boolean-expressions, # (R0916): *Too many boolean expressions in if statement (%s/%s)* - too-many-branches, # (R0912): *Too many branches (%s/%s)* - too-many-instance-attributes, # (R0902): *Too many instance attributes (%s/%s)* - too-many-locals, # (R0914): *Too many local variables (%s/%s)* - too-many-nested-blocks, # (R1702): *Too many nested blocks (%s/%s)* - too-many-public-methods, # (R0904): *Too many public methods (%s/%s)* - too-many-return-statements, # (R0911): *Too many return statements (%s/%s)* - too-many-statements, # (R0915): *Too many statements (%s/%s)* - unspecified-encoding, # (W1514): Using open without explicitly specifying an encoding - use-a-generator, # (R1729): *Use a generator instead '%s(%s)'* - useless-object-inheritance, # (R0205): *Class %r inherits from object, can be safely removed from bases in python3* - useless-return, # (R1711): *Useless return at end of function or method* - diff --git a/ci/3.10.pylintrc b/ci/pylintrc similarity index 98% rename from ci/3.10.pylintrc rename to ci/pylintrc index 43b8172c2..7625abad4 100644 --- a/ci/3.10.pylintrc +++ b/ci/pylintrc @@ -16,7 +16,6 @@ disable=C, # (C) convention, for programming standard violation no-else-continue, # R1724: *Unnecessary "%s" after "continue"* no-else-raise, # R1720: *Unnecessary "%s" after "raise"* no-else-return, # R1705: *Unnecessary "%s" after "return"* - no-self-use, # R0201: Method could be a function protected-access, # W0212: Access to a protected member of a client class raise-missing-from, # W0707: *Consider explicitly re-raising using the 'from' keyword* redundant-u-string-prefix, # The u prefix for strings is no longer necessary in Python >=3.0 diff --git a/tests/common/test_event.py b/tests/common/test_event.py index 435ac2e80..a760c7f9f 100644 --- a/tests/common/test_event.py +++ b/tests/common/test_event.py @@ -60,7 +60,7 @@ def setUp(self): self.event_dir = os.path.join(self.tmp_dir, EVENTS_DIRECTORY) EventLoggerTools.initialize_event_logger(self.event_dir) - threading.current_thread().setName("TestEventThread") + threading.current_thread().name = "TestEventThread" osutil = get_osutil() self.expected_common_parameters = { @@ -70,7 +70,7 @@ def setUp(self): CommonTelemetryEventSchema.ContainerId: AgentGlobals.get_container_id(), CommonTelemetryEventSchema.EventTid: threading.current_thread().ident, CommonTelemetryEventSchema.EventPid: os.getpid(), - CommonTelemetryEventSchema.TaskName: threading.current_thread().getName(), + CommonTelemetryEventSchema.TaskName: threading.current_thread().name, CommonTelemetryEventSchema.KeywordName: json.dumps({"CpuArchitecture": platform.machine()}), # common parameters computed from the OS platform CommonTelemetryEventSchema.OSVersion: EventLoggerTools.get_expected_os_version(), diff --git a/tests/common/test_singletonperthread.py b/tests/common/test_singletonperthread.py index 7b1972635..80dedcb7a 100644 --- a/tests/common/test_singletonperthread.py +++ b/tests/common/test_singletonperthread.py @@ -1,6 +1,6 @@ import uuid from multiprocessing import Queue -from threading import Thread, currentThread +from threading import Thread, current_thread from azurelinuxagent.common.singletonperthread import SingletonPerThread from tests.lib.tools import AgentTestCase, clear_singleton_instances @@ -32,7 +32,7 @@ class TestClassToTestSingletonPerThread(SingletonPerThread): def __init__(self): # Set the name of the object to the current thread name - self.name = currentThread().getName() + self.name = current_thread().name # Unique identifier for a class object self.uuid = str(uuid.uuid4()) @@ -53,8 +53,8 @@ def _setup_multithread_and_execute(self, func1, args1, func2, args2, t1_name=Non t1 = Thread(target=func1, args=args1) t2 = Thread(target=func2, args=args2) - t1.setName(t1_name if t1_name else self.THREAD_NAME_1) - t2.setName(t2_name if t2_name else self.THREAD_NAME_2) + t1.name = t1_name if t1_name else self.THREAD_NAME_1 + t2.name = t2_name if t2_name else self.THREAD_NAME_2 t1.start() t2.start() t1.join() diff --git a/tests/ga/test_multi_config_extension.py b/tests/ga/test_multi_config_extension.py index 0fe8dea5a..127535a54 100644 --- a/tests/ga/test_multi_config_extension.py +++ b/tests/ga/test_multi_config_extension.py @@ -41,7 +41,7 @@ def __init__(self, name, version, state="enabled"): self.version = version self.state = state self.is_invalid_setting = False - self.settings = dict() + self.settings = {} class _TestExtensionObject: def __init__(self, name, seq_no, dependency_level="0", state="enabled"): @@ -94,12 +94,11 @@ def _get_mock_expected_handler_data(self, rc_extensions, vmaccess_extensions, ge def test_it_should_parse_multi_config_settings_properly(self): self.test_data['ext_conf'] = os.path.join(self._MULTI_CONFIG_TEST_DATA, "ext_conf_with_multi_config.xml") - rc_extensions = dict() - rc_extensions["firstRunCommand"] = self._TestExtensionObject(name="firstRunCommand", seq_no=2) - rc_extensions["secondRunCommand"] = self._TestExtensionObject(name="secondRunCommand", seq_no=2, - dependency_level="3") - rc_extensions["thirdRunCommand"] = self._TestExtensionObject(name="thirdRunCommand", seq_no=1, - dependency_level="4") + rc_extensions = { + "firstRunCommand": self._TestExtensionObject(name="firstRunCommand", seq_no=2), + "secondRunCommand": self._TestExtensionObject(name="secondRunCommand", seq_no=2, dependency_level="3"), + "thirdRunCommand": self._TestExtensionObject(name="thirdRunCommand", seq_no=1, dependency_level="4") + } vmaccess_extensions = { "Microsoft.Compute.VMAccessAgent": self._TestExtensionObject(name="Microsoft.Compute.VMAccessAgent", @@ -115,12 +114,11 @@ def test_it_should_parse_multi_config_with_disable_state_properly(self): self.test_data['ext_conf'] = os.path.join(self._MULTI_CONFIG_TEST_DATA, "ext_conf_with_disabled_multi_config.xml") - rc_extensions = dict() - rc_extensions["firstRunCommand"] = self._TestExtensionObject(name="firstRunCommand", seq_no=3) - rc_extensions["secondRunCommand"] = self._TestExtensionObject(name="secondRunCommand", seq_no=3, - dependency_level="1") - rc_extensions["thirdRunCommand"] = self._TestExtensionObject(name="thirdRunCommand", seq_no=1, - dependency_level="4", state="disabled") + rc_extensions = { + "firstRunCommand": self._TestExtensionObject(name="firstRunCommand", seq_no=3), + "secondRunCommand": self._TestExtensionObject(name="secondRunCommand", seq_no=3, dependency_level="1"), + "thirdRunCommand": self._TestExtensionObject(name="thirdRunCommand", seq_no=1, dependency_level="4", state="disabled") + } vmaccess_extensions = { "Microsoft.Compute.VMAccessAgent": self._TestExtensionObject(name="Microsoft.Compute.VMAccessAgent", diff --git a/tests/ga/test_remoteaccess_handler.py b/tests/ga/test_remoteaccess_handler.py index d4f157926..d555c55a8 100644 --- a/tests/ga/test_remoteaccess_handler.py +++ b/tests/ga/test_remoteaccess_handler.py @@ -75,15 +75,14 @@ def mock_add_event(name, op, is_success, version, message): class TestRemoteAccessHandler(AgentTestCase): - eventing_data = [()] + eventing_data = () def setUp(self): super(TestRemoteAccessHandler, self).setUp() # Since ProtocolUtil is a singleton per thread, we need to clear it to ensure that the test cases do not # reuse a previous state clear_singleton_instances(ProtocolUtil) - for data in TestRemoteAccessHandler.eventing_data: - del data + TestRemoteAccessHandler.eventing_data = () # add_user tests @patch('azurelinuxagent.common.utils.cryptutil.CryptUtil.decrypt_secret', return_value="]aPPEv}uNg1FPnl?") diff --git a/tests/lib/tools.py b/tests/lib/tools.py index 11bd80191..194850ee2 100644 --- a/tests/lib/tools.py +++ b/tests/lib/tools.py @@ -29,7 +29,7 @@ import time import unittest from functools import wraps -from threading import currentThread +from threading import current_thread import azurelinuxagent.common.conf as conf import azurelinuxagent.common.event as event @@ -543,6 +543,6 @@ def wrapper(self, *args, **kwargs): def clear_singleton_instances(cls): # Adding this lock to avoid any race conditions with cls._lock: - obj_name = "%s__%s" % (cls.__name__, currentThread().getName()) # Object Name = className__threadName + obj_name = "%s__%s" % (cls.__name__, current_thread().name) # Object Name = className__threadName if obj_name in cls._instances: del cls._instances[obj_name] From ef4245365d6389ff1f0cd65701d6659848020d24 Mon Sep 17 00:00:00 2001 From: narrieta Date: Fri, 23 Feb 2024 16:33:18 -0800 Subject: [PATCH 2/4] . --- .github/workflows/ci_pr.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci_pr.yml b/.github/workflows/ci_pr.yml index b6d27d066..dec8f5093 100644 --- a/.github/workflows/ci_pr.yml +++ b/.github/workflows/ci_pr.yml @@ -150,6 +150,9 @@ jobs: PYLINT_OPTIONS="$PYLINT_OPTIONS --disable=no-self-use" fi + echo "PYLINT_OPTIONS: $PYLINT_OPTIONS" + echo "PYLINT_FILES: $PYLINT_FILES" + pylint $PYLINT_OPTIONS $PYLINT_FILES - name: Test with nosetests From 639235e1c67b9db3bc481b73be6bf34cb2323b48 Mon Sep 17 00:00:00 2001 From: narrieta Date: Fri, 23 Feb 2024 16:52:22 -0800 Subject: [PATCH 3/4] . --- .github/workflows/ci_pr.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci_pr.yml b/.github/workflows/ci_pr.yml index dec8f5093..864c57674 100644 --- a/.github/workflows/ci_pr.yml +++ b/.github/workflows/ci_pr.yml @@ -135,7 +135,7 @@ jobs: # * "unused-private-member" is not implemented on 3.5 and will produce "E0012: Bad option value 'unused-private-member' (bad-option-value)" # so we suppress "bad-option-value". # * 3.9 will produce "no-member" for several properties/methods that are added to the mocks used by the unit tests (e.g - # "E1101: Instance of 'WireProtocol' has no 'aggregate_status' member") so we add them as generated members. + # "E1101: Instance of 'WireProtocol' has no 'aggregate_status' member") so we suppress that warning. # * 'no-self-use' ("R0201: Method could be a function") was moved to an optional extension on 3.9 and is no longer used by default. It needs # to be suppressed for previous versions (3.0-3.8), though. # @@ -144,7 +144,7 @@ jobs: PYLINT_OPTIONS="$PYLINT_OPTIONS --disable=bad-option-value" fi if [[ "${{ matrix.python-version }}" == "3.9" ]]; then - PYLINT_OPTIONS="$PYLINT_OPTIONS --generated-member=WireProtocol.aggregate_status,WireProtocol.incarnation,UpdateHandler._fail_gs_count,UpdateHandler._protocol" + PYLINT_OPTIONS="$PYLINT_OPTIONS --disable=no-member fi if [[ "${{ matrix.python-version }}" =~ ^3\.[0-8]$ ]]; then PYLINT_OPTIONS="$PYLINT_OPTIONS --disable=no-self-use" From 4c7713d7126788b43d31b8642c52a008a44010e4 Mon Sep 17 00:00:00 2001 From: narrieta Date: Fri, 23 Feb 2024 16:54:06 -0800 Subject: [PATCH 4/4] . --- .github/workflows/ci_pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_pr.yml b/.github/workflows/ci_pr.yml index 864c57674..bf308624a 100644 --- a/.github/workflows/ci_pr.yml +++ b/.github/workflows/ci_pr.yml @@ -144,7 +144,7 @@ jobs: PYLINT_OPTIONS="$PYLINT_OPTIONS --disable=bad-option-value" fi if [[ "${{ matrix.python-version }}" == "3.9" ]]; then - PYLINT_OPTIONS="$PYLINT_OPTIONS --disable=no-member + PYLINT_OPTIONS="$PYLINT_OPTIONS --disable=no-member" fi if [[ "${{ matrix.python-version }}" =~ ^3\.[0-8]$ ]]; then PYLINT_OPTIONS="$PYLINT_OPTIONS --disable=no-self-use"