pylint icon indicating copy to clipboard operation
pylint copied to clipboard

pylint: disable=invalid-name pragma gets ignored when using ctypes Structure

Open DScott-2 opened this issue 1 year ago • 0 comments

Bug description

When using the ctypes module, disable=invalid name pragmas get ignored when accessing fields of classes which inherit Structure. Context level, line level and module level ignores all do not work.

Two files: ./example_structure.py

"""Defines things required for the minimal example"""

from ctypes import POINTER, Structure
from ctypes.wintypes import DWORD
from enum import IntEnum

class SERVICE_STATUS(Structure):  # pylint: disable=invalid-name,too-few-public-methods
    """
    Service status structure.

    See:
     https://learn.microsoft.com/en-us/windows/win32/api/winsvc/ns-winsvc-service_status
    """

    _fields_ = [
        ("dwServiceType", DWORD),
        ("dwCurrentState", DWORD),
        ("dwControlsAccepted", DWORD),
        ("dwWin32ExitCode", DWORD),
        ("dwServiceSpecificExitCode", DWORD),
        ("dwCheckPoint", DWORD),
        ("dwWaitHint", DWORD),
    ]


LPSERVICE_STATUS = POINTER(SERVICE_STATUS)

class CurrentState(IntEnum):
    """Windows service manager service status codes"""

    SERVICE_CONTINUE_PENDING = 0x00000005
    SERVICE_PAUSE_PENDING = 0x00000006
    SERVICE_PAUSED = 0x00000007
    SERVICE_RUNNING = 0x00000004
    SERVICE_START_PENDING = 0x00000002
    SERVICE_STOP_PENDING = 0x00000003
    SERVICE_STOPPED = 0x00000001


class ControlsAccepted(IntEnum):
    """Windows service manager accepted service control codes"""

    SERVICE_ACCEPT_NETBINDCHANGE = 0x00000010
    SERVICE_ACCEPT_PARAMCHANGE = 0x00000008
    SERVICE_ACCEPT_PAUSE_CONTINUE = 0x00000002
    SERVICE_ACCEPT_PRESHUTDOWN = 0x00000100
    SERVICE_ACCEPT_SHUTDOWN = 0x00000004
    SERVICE_ACCEPT_STOP = 0x00000001
    SERVICE_ACCEPT_HARDWAREPROFILECHANGE = 0x00000020
    SERVICE_ACCEPT_POWEREVENT = 0x00000040
    SERVICE_ACCEPT_SESSIONCHANGE = 0x00000080
    SERVICE_ACCEPT_TIMECHANGE = 0x00000200
    SERVICE_ACCEPT_TRIGGEREVENT = 0x00000400
    SERVICE_ACCEPT_USERMODEREBOOT = 0x00000800

class ServiceType(IntEnum):
    """Windows service manager service type codes"""

    SERVICE_FILE_SYSTEM_DRIVER = 0x00000002
    SERVICE_KERNEL_DRIVER = 0x00000001
    SERVICE_WIN32_OWN_PROCESS = 0x00000010
    SERVICE_WIN32_SHARE_PROCESS = 0x00000020
    SERVICE_USER_OWN_PROCESS = 0x00000050
    SERVICE_USER_SHARE_PROCESS = 0x00000060
    SERVICE_INTERACTIVE_PROCESS = 0x00000100

Second file, showing issue: ./minimal_example.py

"""Module docstring"""
# pylint: disable=invalid-name, too-few-public-methods
# This disable should prevent invalid-name errors from appearing in report_srv_status and init
# ... but it does not
from example_structure import SERVICE_STATUS, ControlsAccepted, CurrentState, ServiceType



class ExampleService:
    """Class showing spurious pylint errors"""

    def __init__(
        self, name: str, display_name: str, desc: str
    ) -> None:
        self.name = name
        self.desc = desc
        self.display_name = display_name
        self._srv_status: SERVICE_STATUS = SERVICE_STATUS()
        self._srv_status.dwServiceType = ServiceType.SERVICE_WIN32_OWN_PROCESS
        self._srv_status.dwServiceSpecificExitCode = 0

    def report_srv_status(self, current_state: int, win32_exit_code: int, wait_hint: int) -> None:
        """
        Notifies the service controller on the state of the service.
        This is required to tell the controller the service has started or stopped.
        """

        # Update the srv_status object with current state of the service
        self._srv_status.dwCurrentState = current_state
        self._srv_status.dwWin32ExitCode = win32_exit_code
        self._srv_status.dwWaitHint = wait_hint

        if current_state == CurrentState.SERVICE_START_PENDING:
            self._srv_status.dwControlsAccepted = 0
        else:
            self._srv_status.dwControlsAccepted = ControlsAccepted.SERVICE_ACCEPT_STOP

        if current_state in (CurrentState.SERVICE_RUNNING, CurrentState.SERVICE_STOPPED):
            self._srv_status.dwCheckPoint= 0
        else:
            self._srv_status.dwCheckPoint += 1

        # Other stuff excluded ....

Configuration

No response

Command used

"C:\Program Files\Python311\python.exe" -m pylint ./*

Pylint output

************* Module minimal_example
minimal_example.py:19:8: C0103: Attribute name "dwServiceType" doesn't conform to snake_case naming style (invalid-name)
minimal_example.py:20:8: C0103: Attribute name "dwServiceSpecificExitCode" doesn't conform to snake_case naming style (invalid-name)
minimal_example.py:29:8: C0103: Attribute name "dwCurrentState" doesn't conform to snake_case naming style (invalid-name)
minimal_example.py:30:8: C0103: Attribute name "dwWin32ExitCode" doesn't conform to snake_case naming style (invalid-name)
minimal_example.py:31:8: C0103: Attribute name "dwWaitHint" doesn't conform to snake_case naming style (invalid-name)
minimal_example.py:34:12: C0103: Attribute name "dwControlsAccepted" doesn't conform to snake_case naming style (invalid-name)
minimal_example.py:39:12: C0103: Attribute name "dwCheckPoint" doesn't conform to snake_case naming style (invalid-name)

------------------------------------------------------------------
Your code has been rated at 8.70/10 (previous run: 8.70/10, +0.00)

Expected behavior

Clean result, given invalid-name has been disabled

Pylint version

pylint 3.2.2
astroid 3.2.2
Python 3.11.7 (tags/v3.11.7:fa7a6f2, Dec  4 2023, 19:24:49) [MSC v.1937 64 bit (AMD64)]

OS / Environment

Windows 10

Additional dependencies

No response

DScott-2 avatar May 22 '24 02:05 DScott-2