Skip to content
Permalink
Browse files

Disable pylint's non-member check, it's seriously broken in many ways.

Change-Id: Ie3c794b31a78df6d7941fdb4b2ccf3dda97a98ff
  • Loading branch information
svenpanne committed Feb 27, 2020
1 parent 8eadb4f commit fa87c0cbf83560d22513d1c8fca129c6c0baa9f7
Showing with 162 additions and 158 deletions.
  1. +6 −0 .pylintrc
  2. +1 −1 active_checks/check_bi_aggr
  3. +1 −1 active_checks/check_mail
  4. +8 −8 agents/plugins/mk_inotify
  5. +1 −1 agents/plugins/mk_logwatch
  6. +1 −1 agents/plugins/plesk_backups
  7. +1 −1 agents/plugins/plesk_domains
  8. +2 −2 bin/update_rrd_fs_names.py
  9. +1 −1 cmk/__init__.py
  10. +1 −1 cmk/base/autochecks.py
  11. +5 −5 cmk/base/config.py
  12. +2 −2 cmk/base/core_config.py
  13. +1 −1 cmk/base/localize.py
  14. +2 −2 cmk/ec/main.py
  15. +1 −1 cmk/ec/snmp.py
  16. +8 −9 cmk/gui/background_job.py
  17. +2 −2 cmk/gui/backup.py
  18. +3 −3 cmk/gui/config.py
  19. +2 −2 cmk/gui/i18n.py
  20. +5 −5 cmk/gui/inventory.py
  21. +3 −3 cmk/gui/login.py
  22. +1 −1 cmk/gui/plugins/wato/notifications.py
  23. +1 −1 cmk/gui/valuespec.py
  24. +2 −1 cmk/gui/wato/__init__.py
  25. +2 −2 cmk/gui/wato/pages/audit_log.py
  26. +1 −1 cmk/gui/wato/pages/folders.py
  27. +5 −6 cmk/gui/wato/pages/rulesets.py
  28. +3 −3 cmk/gui/wato/pages/sites.py
  29. +1 −1 cmk/gui/watolib/rulesets.py
  30. +1 −1 cmk/gui/watolib/tags.py
  31. +4 −4 cmk/special_agents/agent_3par.py
  32. +1 −1 cmk/special_agents/agent_aws.py
  33. +4 −4 cmk/special_agents/agent_netapp.py
  34. +1 −1 cmk/utils/labels.py
  35. +3 −3 cmk/utils/packaging.py
  36. +2 −3 cmk/utils/werks.py
  37. +2 −2 tests-py3/unit/cmk/base/test_base_crash_reporting.py
  38. +3 −3 tests-py3/unit/omdlib/test_omdlib_backup.py
  39. +3 −3 tests-py3/unit/omdlib/test_omdlib_main.py
  40. +1 −1 tests-py3/unit/omdlib/test_omdlib_skel_permissions.py
  41. +1 −1 tests/integration/agents/special/test_executables.py
  42. +1 −1 tests/unit/checks/generictests/crashtest.py
  43. +3 −3 tests/unit/cmk/base/test_autochecks.py
  44. +14 −14 tests/unit/cmk/base/test_config.py
  45. +1 −1 tests/unit/cmk/base/test_data_sources_cmd_caching.py
  46. +2 −2 tests/unit/cmk/base/test_discovered_labels.py
  47. +1 −1 tests/unit/cmk/base/test_ip_lookup.py
  48. +1 −1 tests/unit/cmk/gui/conftest.py
  49. +2 −2 tests/unit/cmk/gui/test_background_job.py
  50. +4 −4 tests/unit/cmk/gui/test_i18n.py
  51. +2 −2 tests/unit/cmk/gui/test_userdb_ldap_connector.py
  52. +7 −7 tests/unit/cmk/gui/watolib/test_tags.py
  53. +2 −2 tests/unit/cmk/test_update_config.py
  54. +1 −1 tests/unit/cmk/utils/test_labels.py
  55. +6 −6 tests/unit/cmk/utils/test_packaging.py
  56. +6 −6 tests/unit/cmk/utils/test_piggyback.py
  57. +10 −10 tests/unit/livestatus/test_livestatus_unit.py
@@ -124,6 +124,12 @@ disable=
# to our dev dependencies.
wrong-spelling-in-comment,
wrong-spelling-in-docstring,
#---------------------------------------------------------------------------
# Pylint is full of bugs regarding this, leading to tons of false positives
# when pathlib.path is used. Furthermore, the handling of NewTypes is totally
# broken, see e.g. https://github.com/PyCQA/pylint/issues/2296 and
# https://github.com/PyCQA/pylint/issues/3162.
no-member,

[REPORTS]
output-format=cmk_colorized
@@ -149,7 +149,7 @@ if use_automation_user:
username = "automation"
secret_file_path = Path(cmk.utils.paths.var_dir) / "web" / username / "automation.secret"
try:
with secret_file_path.open(encoding="utf-8") as f: # pylint: disable=no-member
with secret_file_path.open(encoding="utf-8") as f:
password = f.read()
except IOError:
sys.stderr.write('Unable to read credentials for "automation" user.\n')
@@ -333,7 +333,7 @@ def forward_to_ec(conn_timeout, messages, forwarded, cleanup_messages, forward_m
sock.send(message + "\n")
sock.close()

elif not forward_method.startswith('spool:'): # pylint: disable=no-member
elif not forward_method.startswith('spool:'):
# write into local event pipe
# Important: When the event daemon is stopped, then the pipe
# is *not* existing! This prevents us from hanging in such
@@ -225,14 +225,14 @@ def do_output(what, event):

map_events = {
# Mode Mask Report_filestats (currently unused)
"access": (pyinotify.IN_ACCESS, False), # pylint: disable=no-member
"open": (pyinotify.IN_OPEN, False), # pylint: disable=no-member
"create": (pyinotify.IN_CREATE, False), # pylint: disable=no-member
"delete": (pyinotify.IN_DELETE, False), # pylint: disable=no-member
"modify": (pyinotify.IN_MODIFY, False), # pylint: disable=no-member
"movedto": (pyinotify.IN_MOVED_TO, False), # pylint: disable=no-member
"movedfrom": (pyinotify.IN_MOVED_FROM, False), # pylint: disable=no-member
"moveself": (pyinotify.IN_MOVE_SELF, False), # pylint: disable=no-member
"access": (pyinotify.IN_ACCESS, False),
"open": (pyinotify.IN_OPEN, False),
"create": (pyinotify.IN_CREATE, False),
"delete": (pyinotify.IN_DELETE, False),
"modify": (pyinotify.IN_MODIFY, False),
"movedto": (pyinotify.IN_MOVED_TO, False),
"movedfrom": (pyinotify.IN_MOVED_FROM, False),
"moveself": (pyinotify.IN_MOVE_SELF, False),
}


@@ -172,7 +172,7 @@ class MEIFolderCleaner(object):
if invalid_dir:
continue

pyinstaller_tmp_path = win32file.GetLongPathName(sys._MEIPASS).lower() # pylint: disable=no-member
pyinstaller_tmp_path = win32file.GetLongPathName(sys._MEIPASS).lower()
if pyinstaller_tmp_path == path.lower():
continue # Skip our own directory

@@ -41,7 +41,7 @@ import MySQLdb

def connect():
# Fix pylint issues in case MySQLdb is not present
# pylint: disable=no-member

try:
return MySQLdb.connect(
host='localhost',
@@ -40,7 +40,7 @@ try:
passwd=open('/etc/psa/.psa.shadow').read().strip(),
charset='utf8',
)
except MySQLdb.Error as e: # pylint: disable=no-member
except MySQLdb.Error as e:
sys.stderr.write("MySQL-Error %d: %s\n" % (e.args[0], e.args[1]))
sys.exit(1)

@@ -68,9 +68,9 @@ def check_df_sources_include_flag():
logger.info("Looking for df.include files...")
for path_dir in checks_dirs:
df_file = path_dir / 'df.include'
if df_file.exists(): # pylint: disable=no-member
if df_file.exists():
logger.info("Inspecting %s", df_file)
with df_file.open('r') as fid: # pylint: disable=no-member
with df_file.open('r') as fid:
r = fid.read()
mat = re.search('^df_use_fs_used_as_metric_name *= *(True|False)', r, re.M)
if not mat:
@@ -30,7 +30,7 @@
def omd_version():
# type: () -> Text
version_link = Path(cmk.utils.paths.omd_root).joinpath("version")
return ensure_unicode(version_link.resolve().name) # pylint: disable=no-member
return ensure_unicode(version_link.resolve().name)


def omd_site():
@@ -391,7 +391,7 @@ def _remove_duplicate_autochecks(autochecks):
def save_autochecks_file(hostname, items):
# type: (HostName, List[DiscoveredService]) -> None
path = _autochecks_path_for(hostname)
path.parent.mkdir(parents=True, exist_ok=True) # pylint: disable=no-member
path.parent.mkdir(parents=True, exist_ok=True)
content = []
content.append("[")
for discovered_service in sorted(items, key=lambda s: (s.check_plugin_name, s.item)):
@@ -334,10 +334,10 @@ def _load_config(with_conf_d, exclude_parents_mk):
"FOLDER_PATH": folder_path,
})

all_hosts.set_current_path(current_path) # pylint: disable=no-member
clusters.set_current_path(current_path) # pylint: disable=no-member
all_hosts.set_current_path(current_path)
clusters.set_current_path(current_path)

exec(open(_f).read(), global_dict, global_dict)
exec (open(_f).read(), global_dict, global_dict)

if not isinstance(all_hosts, SetFolderPathList):
raise MKGeneralException(
@@ -647,7 +647,7 @@ def load(self):
# type: () -> None
_initialize_config()
with open(self._path, "rb") as f:
exec(marshal.load(f), globals())
exec (marshal.load(f), globals())
_perform_post_config_loading_actions()


@@ -1685,7 +1685,7 @@ def load_precompiled_plugin(path, check_context):
store.makedirs(os.path.dirname(precompiled_path))
py_compile.compile(path, precompiled_path, doraise=True)

exec(marshal.loads(open(precompiled_path, "rb").read()[header_size:]), check_context)
exec (marshal.loads(open(precompiled_path, "rb").read()[header_size:]), check_context)


def _is_plugin_precompiled(path, precompiled_path):
@@ -243,7 +243,7 @@ def do_create_config(core, with_agents):
if with_agents:
try:
import cmk.base.cee.agent_bakery # pylint: disable=redefined-outer-name,import-outside-toplevel
cmk.base.cee.agent_bakery.bake_on_restart() # pylint: disable=no-member
cmk.base.cee.agent_bakery.bake_on_restart()
except ImportError:
pass

@@ -469,7 +469,7 @@ def get_host_attributes(hostname, config_cache):
attrs["_ACTIONS"] = ",".join(actions)

if cmk.is_managed_edition():
attrs["_CUSTOMER"] = config.current_customer # type: ignore[attr-defined] # pylint: disable=no-member
attrs["_CUSTOMER"] = config.current_customer # type: ignore[attr-defined]

return attrs

@@ -44,7 +44,7 @@ def _locale_base():
def _pot_file():
# type: () -> str
local_pot_file = cmk.utils.paths.local_locale_dir / 'multisite.pot'
if local_pot_file.exists(): # pylint: disable=no-member
if local_pot_file.exists():
return str(local_pot_file)
return _locale_base() + '/multisite.pot'

@@ -856,13 +856,13 @@ def serve(self):
# Accept new connection on event unix socket
if self._eventsocket in readable:
client_socket, address = self._eventsocket.accept()
# pylint: disable=no-member

client_sockets[client_socket.fileno()] = (client_socket, address, b"")

# Same for the TCP syslog socket
if self._syslog_tcp and self._syslog_tcp in readable:
client_socket, address = self._syslog_tcp.accept()
# pylint: disable=no-member

client_sockets[client_socket.fileno()] = (client_socket, address, b"")

# Read data from existing event unix socket connections
@@ -246,7 +246,7 @@ def _translate_via_mibs(self, ipaddress, var_bind_list):

def do_translate(oid, value):
# Disable mib_var[0] type detection
# pylint: disable=no-member

mib_var = pysnmp.smi.rfc1902.ObjectType(pysnmp.smi.rfc1902.ObjectIdentity(oid),
value).resolveWithMib(self._mib_resolver)

@@ -95,7 +95,7 @@ def send_result_message(self, info):

result_message_path = Path(
self.get_work_dir()) / BackgroundJobDefines.result_message_filename
with result_message_path.open("ab") as f: # pylint: disable=no-member
with result_message_path.open("ab") as f:
f.write(six.ensure_binary(encoded_info))

def send_exception(self, info):
@@ -105,7 +105,7 @@ def send_exception(self, info):
# Exceptions also get an extra newline, since some error messages tend not output a \n at the end..
encoded_info = "%s\n" % six.ensure_str(info)
sys.stdout.write(encoded_info)
with (Path(self.get_work_dir()) / BackgroundJobDefines.exceptions_filename).open("ab") as f: # pylint: disable=no-member
with (Path(self.get_work_dir()) / BackgroundJobDefines.exceptions_filename).open("ab") as f:
f.write(six.ensure_binary(encoded_info))


@@ -224,9 +224,8 @@ def _open_stdout_and_stderr(self):
# - Use buffering=0 to make the non flushed output directly visible in
# the job progress dialog
# - Python 3's stdout and stderr expect 'str' not 'bytes'
unbuffered = (
Path(self.get_work_dir()) / # pylint: disable=no-member
BackgroundJobDefines.progress_update_filename).open("wb", buffering=0)
unbuffered = (Path(self.get_work_dir()) /
BackgroundJobDefines.progress_update_filename).open("wb", buffering=0)

if sys.version_info[0] >= 3:
sys.stdout = sys.stderr = io.TextIOWrapper(unbuffered, write_through=True)
@@ -562,7 +561,7 @@ def __init__(self, work_dir):

def get_status_from_file(self):
# type: () -> JobStatusSpec
if not self._jobstatus_path.exists(): # pylint: disable=no-member
if not self._jobstatus_path.exists():
data = {} # type: JobStatusSpec
data["state"] = "initialized"
else:
@@ -583,7 +582,7 @@ def get_status_from_file(self):
for field_id, field_path in [("JobProgressUpdate", self._progress_update_path),
("JobResult", self._result_message_path),
("JobException", self._exceptions_path)]:
if field_path.exists(): # pylint: disable=no-member
if field_path.exists():
data["loginfo"][field_id] = open(str(field_path)).read().splitlines()
else:
data["loginfo"][field_id] = []
@@ -600,11 +599,11 @@ def get_status_from_file(self):

def statusfile_exists(self):
# type: () -> bool
return self._jobstatus_path.exists() # pylint: disable=no-member
return self._jobstatus_path.exists()

def update_status(self, params):
# type: (JobStatusSpec) -> None
if not self._jobstatus_path.parent.exists(): # pylint: disable=no-member
if not self._jobstatus_path.parent.exists():
return

if params:
@@ -1214,14 +1214,14 @@ def ident(self):
def choices(cls):
choices = []
# TODO: subclasses with the same name may be registered multiple times, due to execfile
for type_class in cls.__subclasses__(): # pylint: disable=no-member
for type_class in cls.__subclasses__():
choices.append((type_class.ident, type_class.title(), type_class.valuespec()))
return sorted(choices, key=lambda x: x[1])

@classmethod
def get_type(cls, type_ident):
# TODO: subclasses with the same name may be registered multiple times, due to execfile
for type_class in cls.__subclasses__(): # pylint: disable=no-member
for type_class in cls.__subclasses__():
if type_class.ident == type_ident:
return type_class

@@ -1009,7 +1009,7 @@ def _migrate_pre_16_socket_config(site_cfg):
def _migrate_string_encoded_socket(value):
# type: (AnyStr) -> Tuple[str, Union[Dict]]
str_value = six.ensure_str(value)
family_txt, address = str_value.split(":", 1) # pylint: disable=no-member
family_txt, address = str_value.split(":", 1)

if family_txt == "unix":
return "unix", {
@@ -1263,10 +1263,10 @@ def theme_choices():
continue

theme_base_dir = base_dir / "htdocs" / "themes"
if not theme_base_dir.exists(): # pylint: disable=no-member
if not theme_base_dir.exists():
continue

for theme_dir in theme_base_dir.iterdir(): # pylint: disable=no-member
for theme_dir in theme_base_dir.iterdir():
meta_file = theme_dir / "theme.json"
if not meta_file.exists():
continue
@@ -86,9 +86,9 @@ def _get_package_language_dirs():
are then used in addition to the builtin and local localization files.
"""
package_locale_dir = cmk.utils.paths.local_locale_dir / "packages"
if not package_locale_dir.exists(): # pylint: disable=no-member
if not package_locale_dir.exists():
return []
return list(package_locale_dir.iterdir()) # pylint: disable=no-member
return list(package_locale_dir.iterdir())


def get_language_alias(lang):
@@ -492,21 +492,21 @@ def __init__(self):
self._inventory_delta_cache_path = Path(cmk.utils.paths.var_dir) / "inventory_delta_cache"

def run(self):
if not self._inventory_delta_cache_path.exists() or not self._inventory_archive_path.exists( # pylint: disable=no-member
if not self._inventory_delta_cache_path.exists() or not self._inventory_archive_path.exists(
):
return

last_cleanup = self._inventory_delta_cache_path / "last_cleanup"
# TODO: remove with pylint 2
if last_cleanup.exists() and time.time() - last_cleanup.stat().st_mtime < 3600 * 12: # pylint: disable=no-member
if last_cleanup.exists() and time.time() - last_cleanup.stat().st_mtime < 3600 * 12:
return

# TODO: remove with pylint 2
inventory_archive_hosts = {
x.name for x in self._inventory_archive_path.iterdir() if x.is_dir() # pylint: disable=no-member
x.name for x in self._inventory_archive_path.iterdir() if x.is_dir()
}
inventory_delta_cache_hosts = {
x.name for x in self._inventory_delta_cache_path.iterdir() if x.is_dir() # pylint: disable=no-member
x.name for x in self._inventory_delta_cache_path.iterdir() if x.is_dir()
}

folders_to_delete = inventory_delta_cache_hosts - inventory_archive_hosts
@@ -532,7 +532,7 @@ def run(self):
(self._inventory_delta_cache_path / hostname / filename).unlink()

# TODO: remove with pylint 2
last_cleanup.touch() # pylint: disable=no-member
last_cleanup.touch()

def _get_timestamps_for_host(self, hostname):
timestamps = {"None"} # 'None' refers to the histories start
@@ -95,8 +95,8 @@ def _load_secret():
secret_path = htpasswd_path.parent.joinpath('auth.secret')

secret = u''
if secret_path.exists(): # pylint: disable=no-member
with secret_path.open(encoding="utf-8") as f: # pylint: disable=no-member
if secret_path.exists():
with secret_path.open(encoding="utf-8") as f:
secret = f.read().strip()

# Create new secret when this installation has no secret
@@ -107,7 +107,7 @@ def _load_secret():
# renew their login after update.
if secret == '' or len(secret) == 32:
secret = _generate_secret()
with secret_path.open("w", encoding="utf-8") as f: # pylint: disable=no-member
with secret_path.open("w", encoding="utf-8") as f:
f.write(secret)

return secret
@@ -246,7 +246,7 @@ def _parameter_elements(self):
])

if not cmk.is_raw_edition():
elements += cmk.gui.cee.plugins.wato.syncsmtp.cee_html_mail_smtp_sync_option # pylint: disable=no-member
elements += cmk.gui.cee.plugins.wato.syncsmtp.cee_html_mail_smtp_sync_option

return elements

@@ -1014,7 +1014,7 @@ def __init__( # pylint: disable=redefined-builtin
def idents(cls):
# type: () -> Dict[str, Type[TextAsciiAutocomplete]]
idents = {}
for type_class in cls.__subclasses__(): # pylint: disable=no-member
for type_class in cls.__subclasses__():
idents[type_class.ident] = type_class
return idents

@@ -413,7 +413,8 @@ def page_handler():
" in your <tt>multisite.mk</tt> if you want to use WATO."))

# config.current_customer can not be checked with CRE repos
if cmk.is_managed_edition() and not managed.is_provider(config.current_customer): # type: ignore[attr-defined] # pylint: disable=no-member
if cmk.is_managed_edition() and not managed.is_provider(
config.current_customer): # type: ignore[attr-defined]
raise MKGeneralException(
_("Check_MK can only be configured on "
"the managers central site."))

0 comments on commit fa87c0c

Please sign in to comment.
You can’t perform that action at this time.