New: [rhinstaller/anaconda/pulls/89 master] Set the GUI-selected environment in the ksdata (#1192100)
by dashea
This way an environment selected in the GUI and an environment selected
in kickstart are treated in the same way. This fixes the problem where
changing payloads forgets the previous environment selection, and it
changes the generated %packages section of anaconda-ks.cfg to contain
the environment information instead of a list of the groups in the
environment.
This commit restores the dnf _select_environment method removed in
602f47dcd5d7543f66dc6833685d0e810595acb5, but modifies it so that the
environment is both selected in dnf and in the kickstart data.
--
To view this pull request on github, visit https://github.com/rhinstaller/anaconda/pull/89
9 years
[lorax] Add product.img support for s390 templates
by Dan Horák
---
share/live/s390.tmpl | 10 ++++++++++
share/s390.tmpl | 17 +++++++++++++++++
2 files changed, 27 insertions(+)
diff --git a/share/live/s390.tmpl b/share/live/s390.tmpl
index f02963d..86e020d 100644
--- a/share/live/s390.tmpl
+++ b/share/live/s390.tmpl
@@ -4,6 +4,7 @@ configdir="tmp/config_files/s390"
BOOTDIR="images"
KERNELDIR=BOOTDIR
INITRD_ADDRESS="0x02000000"
+LORAXDIR="usr/share/lorax/"
# The assumption seems to be that there is only one s390 kernel, ever
kernel = kernels[0]
%>
@@ -31,3 +32,12 @@ createaddrsize ${INITRD_ADDRESS} ${outroot}/${BOOTDIR}/initrd.img ${outroot}/${B
treeinfo images-${basearch} initrd.addrsize ${BOOTDIR}/initrd.addrsize
treeinfo images-${basearch} generic.prm ${BOOTDIR}/generic.prm
treeinfo images-${basearch} generic.ins generic.ins
+
+# Create optional product.img and updates.img
+<% imggraft=""; images=["product", "updates"] %>
+%for img in images:
+ %if exists("%s/%s/" % (LORAXDIR, img)):
+ installimg ${LORAXDIR}/${img}/ images/${img}.img
+ <% imggraft += " images/{0}.img={1}/images/{0}.img".format(img, outroot) %>
+ %endif
+%endfor
diff --git a/share/s390.tmpl b/share/s390.tmpl
index fa712fd..9d7eb00 100644
--- a/share/s390.tmpl
+++ b/share/s390.tmpl
@@ -4,6 +4,7 @@ configdir="tmp/config_files/s390"
BOOTDIR="images"
KERNELDIR=BOOTDIR
INITRD_ADDRESS="0x02000000"
+LORAXDIR="usr/share/lorax/"
# The assumption seems to be that there is only one s390 kernel, ever
kernel = kernels[0]
%>
@@ -38,3 +39,19 @@ treeinfo images-${basearch} initrd.addrsize ${BOOTDIR}/initrd.addrsize
treeinfo images-${basearch} generic.prm ${BOOTDIR}/generic.prm
treeinfo images-${basearch} genericdvd.prm ${BOOTDIR}/genericdvd.prm
treeinfo images-${basearch} generic.ins generic.ins
+
+# Create optional product.img and updates.img
+<% imggraft=""; images=["product", "updates"] %>
+%for img in images:
+ %if exists("%s/%s/" % (LORAXDIR, img)):
+ installimg ${LORAXDIR}/${img}/ images/${img}.img
+ <% imggraft += " images/{0}.img={1}/images/{0}.img".format(img, outroot) %>
+ %endif
+%endfor
+
+# Inherit iso-graft/ if it exists from external templates
+<%
+ import os
+ if os.path.exists(workdir + "/iso-graft"):
+ imggraft += " " + workdir + "/iso-graft"
+%>
--
1.9.3
9 years
Re: [Patch for Review] iSCSI Name Validation using regex.
by Sujith Pandel
Hi Chris,
I did a few changes to the previously sent patch. Also added the test script for regexes' validation.
Please have a look and let me know your thoughts on them.
Regarding the lookaheads and the dots, I feel regexes might need major changes to accomodate those changes.
I have added few comments for the regexes also. Feel free to add/modify them, if required.
Thanks and Regards,
Sujith Pandel
When adding iSCSI target disk during installation, the iSCSI Initiator name and the Target IP is validated to enable/disable the "Start Discovery" button on the page.
Currently, the validation of iSCSI Initiator Name is based on the existence of dots only (".") and this can be more efficiently done by using a regular expression.
The conditions for iSCSI initiator name used in this regex are
(https://tools.ietf.org/html/rfc3720#section-3.2.6.3.1 , https://tools.ietf.org/html/rfc3721#page-5 and http://standards.ieee.org/regauth/oui/tutorials/EUI64.html):
1. For iqn format:
a. Starts with string 'iqn.'
b. A date code specifying the year and month in which the organization registered the domain or sub-domain name used as the naming authority string. "yyyy-mm"
c. A dot (".")
d. The organizational naming authority string, which consists of a valid, reversed domain or subdomain name.
e. Optionally, a colon (":"), followed by a string of the assigning organization's choosing, which must make each assigned iSCSI name unique. With the exception of the colon prefix, the owner of the domain name can assign everything after the reversed domain name as desired.
2. For eui format:
The format is "eui." followed by an EUI-64 identifier (16 ASCII-encoded hexadecimal digits).
Signed-off-by: Sujith Pandel <sujithpshankar(a)gmail.com>
---
pyanaconda/regexes.py | 19 +++++++
pyanaconda/ui/gui/spokes/advstorage/iscsi.py | 9 +++-
tests/regex_tests/iscsi_name_test.py | 78 ++++++++++++++++++++++++++++
3 files changed, 104 insertions(+), 2 deletions(-)
create mode 100644 tests/regex_tests/iscsi_name_test.py
diff --git a/pyanaconda/regexes.py b/pyanaconda/regexes.py
index b4e52a3..a30b451 100644
--- a/pyanaconda/regexes.py
+++ b/pyanaconda/regexes.py
@@ -135,3 +135,22 @@ REPO_NAME_VALID = re.compile(r'^[a-zA-Z0-9_.:-]+$')
# Product Version string, just the starting numbers like 21 or 21.1
VERSION_DIGITS = r'([\d.]+)'
+
+
+#Regexes to validate iSCSI Names according to RFC 3720 and RFC 3721
+#The conditions for iSCSI name used in the following regexes are
+#(https://tools.ietf.org/html/rfc3720#section-3.2.6.3.1 , https://tools.ietf.org/html/rfc3721#page-5 and http://standards.ieee.org/regauth/oui/tutorials/EUI64.html):
+#1. For iqn format:
+# a. Starts with string 'iqn.'
+# b. A date code specifying the year and month in which the organization registered the domain or sub-domain name used as the naming authority string. "yyyy-mm"
+# c. A dot (".")
+# d. The organizational naming authority string, which consists of a valid, reversed domain or subdomain name.
+# e. Optionally, a colon (":"), followed by a string of the assigning organization's choosing, which must make each assigned iSCSI name unique. With the exception of the colon prefix, the owner of the domain name can assign everything after the reversed domain name as desired.
+
+#2. For eui format:
+# a. The format is "eui." followed by an EUI-64 identifier (16 ASCII-encoded hexadecimal digits).
+ISCSI_IQN_NAME_REGEX = re.compile(r'^iqn\.\d{4}-\d{2}((?<!-)\.(?!-)[a-zA-Z0-9\-]+){1,63}(?<!-)(?<!\.)(:[^:]+)?$')
+
+ISCSI_EUI_NAME_REGEX = re.compile(r'^eui\.[a-fA-F0-9]{16}$')
+
+
diff --git a/pyanaconda/ui/gui/spokes/advstorage/iscsi.py b/pyanaconda/ui/gui/spokes/advstorage/iscsi.py
index 22e11c3..26c34c3 100644
--- a/pyanaconda/ui/gui/spokes/advstorage/iscsi.py
+++ b/pyanaconda/ui/gui/spokes/advstorage/iscsi.py
@@ -18,7 +18,7 @@
#
# Red Hat Author(s): Chris Lumens <clumens(a)redhat.com>
#
-
+import re
from IPy import IP
from collections import namedtuple
from gi.repository import GLib
@@ -29,6 +29,7 @@ from pyanaconda.ui.gui import GUIObject
from pyanaconda.ui.gui.utils import escape_markup
from pyanaconda.i18n import _
from pyanaconda import nm
+from pyanaconda.regexes import ISCSI_IQN_NAME_REGEX, ISCSI_EUI_NAME_REGEX
__all__ = ["ISCSIDialog"]
@@ -303,7 +304,11 @@ class ISCSIDialog(GUIObject):
stripped = text.strip()
#iSCSI Naming Standards: RFC 3720 and RFC 3721
- return "." in stripped
+ #iSCSI Name validation using regex. Name should either match IQN format or EUI format.
+ if re.match(ISCSI_IQN_NAME_REGEX,stripped) or re.match(ISCSI_EUI_NAME_REGEX,stripped):
+ return True
+ else:
+ return False
def on_discover_field_changed(self, *args):
# Make up a credentials object so we can test if it's valid.
diff --git a/tests/regex_tests/iscsi_name_test.py b/tests/regex_tests/iscsi_name_test.py
new file mode 100644
index 0000000..8571396
--- /dev/null
+++ b/tests/regex_tests/iscsi_name_test.py
@@ -0,0 +1,78 @@
+#!/usr/bin/python
+# vim:set fileencoding=utf-8
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Author(s): Sujith Pandel <sujithpshankar(a)gmail.com>
+# Ajith Pandel <ajithpandel(a)gmail.com>
+#
+import unittest
+import re
+
+from regexcheck import regex_match
+from pyanaconda.regexes import ISCSI_IQN_NAME_REGEX, ISCSI_EUI_NAME_REGEX
+
+class iSCSIiqnnameRegexTestCase(unittest.TestCase):
+ def iqnname_test(self):
+ good_tests = [
+ 'iqn.2014-15.com.example',
+ 'iqn.2014-15.com.example:iscsi',
+ 'iqn.2014-15.c-om.example:iscsi',
+ 'iqn.2014-15.c.om.example:iscsi',
+ 'iqn.2014-15.com.example:...',
+ 'iqn.2014-15.com.example:iscsi_@nything_except_colon_after_colon!'
+ ]
+
+ bad_tests = [
+ 'iqn',
+ 'iqn.',
+ 'iqn.2014-15',
+ 'iqn.2014-15.',
+ 'iqn.2014-15..',
+ 'iqn.2014-15.com.example.',
+ 'iqn.2014-15.com.example...',
+ 'iqn.2014-15.com.example:',
+ 'iqn.2014-15.-com.example',
+ 'iqn.2014-15.com-.example',
+ 'iqn.2014-15.-.example',
+ 'iqn.2014-15.com.example-:iscsi',
+ 'abciqn.2014-15.com.example:iscsi',
+ 'iqn.2014-15.-.example:iscsi',
+ 'iqn.2014-15.com&com.example:iscsi',
+ 'iqn.2014-15.com.example:iscsi:doublecolon',
+ 'iqn.2014-15..om.example:iscsi',
+ ]
+
+ if not regex_match(ISCSI_IQN_NAME_REGEX, good_tests, bad_tests):
+ self.fail()
+
+class iSCSIeuinameRegexTestCase(unittest.TestCase):
+ def euiname_test(self):
+ good_tests = [
+ 'eui.ABCDEF0123456789',
+ 'eui.abcdef0123456789',
+ 'eui.0123456789ABCDEF'
+ ]
+
+ bad_tests = [
+ 'eui',
+ 'eui.',
+ 'eui.2014-',
+ 'eui.exampleeui789abc'
+ 'eui.AAAABBBBCCC2345',
+ 'eui.AAAABBBBCCCCD4567'
+ ]
+
+ if not regex_match(ISCSI_EUI_NAME_REGEX, good_tests, bad_tests):
+ self.fail()
--
2.1.0
9 years
[PATCH 01/11] Move blivet to using pocketlint.
by Chris Lumens
There's a fair number of errors right now, some of which could be false
positives, but I am going to take care of those in subsequent commits.
---
Makefile | 3 +
python-blivet.spec | 2 +
tests/pylint/intl.py | 63 ---------
tests/pylint/pointless-override.py | 273 ------------------------------------
tests/pylint/pylint-false-positives | 28 ----
tests/pylint/pylint-one.sh | 33 -----
tests/pylint/runpylint.py | 34 +++++
tests/pylint/runpylint.sh | 125 -----------------
8 files changed, 39 insertions(+), 522 deletions(-)
delete mode 100644 tests/pylint/intl.py
delete mode 100644 tests/pylint/pointless-override.py
delete mode 100644 tests/pylint/pylint-false-positives
delete mode 100755 tests/pylint/pylint-one.sh
create mode 100755 tests/pylint/runpylint.py
delete mode 100755 tests/pylint/runpylint.sh
diff --git a/Makefile b/Makefile
index 9f60551..a55f500 100644
--- a/Makefile
+++ b/Makefile
@@ -36,6 +36,9 @@ coverage:
PYTHONPATH=.:tests/ coverage run --branch -m unittest discover -v -s tests/ -p '*_test.py'
coverage report --include="blivet/*"
+check:
+ PYTHONPATH=. tests/pylint/runpylint.py
+
clean:
-rm *.tar.gz blivet/*.pyc blivet/*/*.pyc ChangeLog
$(MAKE) -C po clean
diff --git a/python-blivet.spec b/python-blivet.spec
index eeaaba8..ef4bacb 100644
--- a/python-blivet.spec
+++ b/python-blivet.spec
@@ -13,6 +13,7 @@ Source0: http://github.com/dwlehman/blivet/archive/%{realname}-%{version}.tar.gz
# Versions of required components (done so we make sure the buildrequires
# match the requires versions of things).
%define pykickstartver 1.99.22
+%define pocketlintver 0.4
%define partedver 1.8.1
%define pypartedver 3.10.3
%define e2fsver 1.41.0
@@ -22,6 +23,7 @@ Source0: http://github.com/dwlehman/blivet/archive/%{realname}-%{version}.tar.gz
BuildArch: noarch
BuildRequires: gettext
BuildRequires: python-setuptools
+BuildRequires: python3-pocketlint >= %{pocketlintver}
%if 0%{with_python3}
BuildRequires: python3-devel python3-setuptools
diff --git a/tests/pylint/intl.py b/tests/pylint/intl.py
deleted file mode 100644
index 3052680..0000000
--- a/tests/pylint/intl.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# I18N-related pylint module
-#
-# Copyright (C) 2013 Red Hat, Inc.
-#
-# This copyrighted material is made available to anyone wishing to use,
-# modify, copy, or redistribute it subject to the terms and conditions of
-# the GNU General Public License v.2, or (at your option) any later version.
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY expressed or implied, including the implied warranties of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-# Public License for more details. You should have received a copy of the
-# GNU General Public License along with this program; if not, write to the
-# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the
-# source code or documentation are not subject to the GNU General Public
-# License and may only be used or replicated with the express permission of
-# Red Hat, Inc.
-#
-# Red Hat Author(s): Chris Lumens <clumens(a)redhat.com>
-#
-
-import astroid
-
-from pylint.checkers import BaseChecker
-from pylint.checkers.utils import check_messages
-from pylint.interfaces import IAstroidChecker
-
-translationMethods = ["_", "N_", "P_", "C_", "CN_", "CP_"]
-
-class IntlChecker(BaseChecker):
- __implements__ = (IAstroidChecker, )
- name = "internationalization"
- msgs = {"W9901": ("Found % in a call to a _() method",
- "found-percent-in-_",
- "% in a call to one of the _() methods results in incorrect translations"),
- "W9902": ("Found _ call at module/class level",
- "found-_-in-module-class",
- "Calling _ at the module or class level results in translations to the wrong language")
- }
-
- @check_messages("W9901")
- def visit_binop(self, node):
- if node.op != "%":
- return
-
- curr = node
- while curr.parent:
- if isinstance(curr.parent, astroid.CallFunc) and getattr(curr.parent.func, "name", "") in translationMethods:
- self.add_message("W9901", node=node)
- break
-
- curr = curr.parent
-
- @check_messages("W9902")
- def visit_callfunc(self, node):
- # The first test skips internal functions like getattr.
- if isinstance(node.func, astroid.Name) and node.func.name == "_":
- if isinstance(node.scope(), astroid.Module) or isinstance(node.scope(), astroid.Class):
- self.add_message("W9902", node=node)
-
-def register(linter):
- """required method to auto register this checker """
- linter.register_checker(IntlChecker(linter))
diff --git a/tests/pylint/pointless-override.py b/tests/pylint/pointless-override.py
deleted file mode 100644
index e5f0fd8..0000000
--- a/tests/pylint/pointless-override.py
+++ /dev/null
@@ -1,273 +0,0 @@
-# Pylint checker for pointless class attributes overrides.
-#
-# Copyright (C) 2014 Red Hat, Inc.
-#
-# This copyrighted material is made available to anyone wishing to use,
-# modify, copy, or redistribute it subject to the terms and conditions of
-# the GNU General Public License v.2, or (at your option) any later version.
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY expressed or implied, including the implied warranties of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-# Public License for more details. You should have received a copy of the
-# GNU General Public License along with this program; if not, write to the
-# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the
-# source code or documentation are not subject to the GNU General Public
-# License and may only be used or replicated with the express permission of
-# Red Hat, Inc.
-#
-# Red Hat Author(s): Anne Mulhern <amulhern(a)redhat.com>
-#
-
-import abc
-
-from six import add_metaclass
-
-import astroid
-
-from pylint.checkers import BaseChecker
-from pylint.checkers.utils import check_messages
-from pylint.interfaces import IAstroidChecker
-
-(a)add_metaclass(abc.ABCMeta)
-class PointlessData(object):
-
- _DEF_CLASS = abc.abstractproperty(doc="Class of interesting definitions.")
- message_id = abc.abstractproperty(doc="Pylint message identifier.")
-
- @classmethod
- @abc.abstractmethod
- def _retain_node(cls, node, restrict=True):
- """ Determines whether to retain a node for the analysis.
-
- :param node: an AST node
- :type node: astroid.Class
- :param restrict bool: True if results returned should be restricted
- :returns: True if the node should be kept, otherwise False
- :rtype: bool
-
- Restricted nodes are candidates for being marked as overridden.
- Only restricted nodes are put into the initial pool of candidates.
- """
- raise NotImplementedError()
-
- @staticmethod
- @abc.abstractmethod
- def _extract_value(node):
- """ Return the node that contains the assignment's value.
-
- :param node: an AST node
- :type node: astroid.Class
- :returns: the node corresponding to the value
- :rtype: bool
- """
- raise NotImplementedError()
-
- @staticmethod
- @abc.abstractmethod
- def _extract_targets(node):
- """ Generates the names being assigned to.
-
- :param node: an AST node
- :type node: astroid.Class
- :returns: a list of assignment target names
- :rtype: generator of str
- """
- raise NotImplementedError()
-
- @classmethod
- def get_data(cls, node, restrict=True):
- """ Find relevant nodes for this analysis.
-
- :param node: an AST node
- :type node: astroid.Class
- :param restrict bool: True if results returned should be restricted
-
- :rtype: generator of astroid.Class
- :returns: a generator of interesting nodes.
-
- Note that all nodes returned are guaranteed to be instances of
- some class in self._DEF_CLASS.
- """
- nodes = (n for n in node.body if isinstance(n, cls._DEF_CLASS))
- for n in nodes:
- if cls._retain_node(n, restrict):
- for name in cls._extract_targets(n):
- yield (name, cls._extract_value(n))
-
- @classmethod
- @abc.abstractmethod
- def check_equal(cls, node, other):
- """ Check whether the two nodes are considered equal.
-
- :param node: some ast node
- :param other: some ast node
-
- :rtype: bool
- :returns: True if the nodes are considered equal, otherwise False
-
- If the method returns True, the nodes are actually equal, but it
- may return False when the nodes are equal.
- """
- raise NotImplementedError()
-
-class PointlessFunctionDefinition(PointlessData):
- """ Looking for pointless function definitions. """
-
- _DEF_CLASS = astroid.Function
- message_id = "W9952"
-
- @classmethod
- def _retain_node(cls, node, restrict=True):
- return not restrict or \
- (len(node.body) == 1 and isinstance(node.body[0], astroid.Pass))
-
- @classmethod
- def check_equal(cls, node, other):
- return len(node.body) == 1 and isinstance(node.body[0], astroid.Pass) and \
- len(other.body) == 1 and isinstance(other.body[0], astroid.Pass)
-
- @staticmethod
- def _extract_value(node):
- return node
-
- @staticmethod
- def _extract_targets(node):
- yield node.name
-
-class PointlessAssignment(PointlessData):
-
- _DEF_CLASS = astroid.Assign
- message_id = "W9951"
-
- _VALUE_CLASSES = (
- astroid.CallFunc,
- astroid.Const,
- astroid.Dict,
- astroid.List,
- astroid.Tuple
- )
-
- @classmethod
- def _retain_node(cls, node, restrict=True):
- return not restrict or isinstance(node.value, cls._VALUE_CLASSES)
-
- @classmethod
- def check_equal(cls, node, other):
- if type(node) != type(other):
- return False
- if isinstance(node, astroid.Const):
- return node.value == other.value
- if isinstance(node, (astroid.List, astroid.Tuple)):
- return len(node.elts) == len(other.elts) and \
- all(cls.check_equal(n, o) for (n, o) in zip(node.elts, other.elts))
- if isinstance(node, astroid.Dict):
- return len(node.items) == len(other.items) and \
- all(cls.check_equal(n, o) for (n, o) in zip(sorted(node.items), sorted(other.items)))
- if isinstance(node, astroid.CallFunc):
- if type(node.func) != type(other.func):
- return False
-
- if isinstance(node.func, astroid.Getattr):
- if node.func.attrname != other.func.attrname or \
- type(node.func.expr) != type(other.func.expr) or \
- node.func.expr.name != other.func.expr.name:
- return False
- elif isinstance(node.func, astroid.Name):
- if node.func.name != other.func.name:
- return False
- else:
- return False
-
- return node.starargs == other.starargs and \
- node.kwargs == other.kwargs and \
- node.args == other.args
-
- return False
-
- @staticmethod
- def _extract_value(node):
- return node.value
-
- @staticmethod
- def _extract_targets(node):
- for target in node.targets:
- yield target.name
-
-class PointlessClassAttributeOverrideChecker(BaseChecker):
- """ If the nearest definition of the class attribute in the MRO assigns
- it the same value, then the overriding definition is said to be
- pointless.
-
- The algorithm for detecting a pointless attribute override is the following.
-
- * For each class, C:
- - For each attribute assignment,
- name_1 = name_2 ... name_n = l (where l is a literal):
- * For each n in (n_1, n_2):
- - Traverse the linearization of the MRO until the first
- matching assignment n = l' is identified. If l is equal to l',
- then consider that the assignment to l in C is a
- pointless override.
-
- The algorithm for detecting a pointless method override has the same
- general structure, and the same defects discussed below.
-
- Note that this analysis is neither sound nor complete. It is unsound
- under multiple inheritance. Consider the following class hierarchy::
-
- class A(object):
- _attrib = False
-
- class B(A):
- _attrib = False
-
- class C(A):
- _attrib = True
-
- class D(B,C):
- pass
-
- In this case, starting from B, B._attrib = False would be considered
- pointless. However, for D the MRO is B, C, A, and removing the assignment
- B._attrib = False would change the inherited value of D._attrib from
- False to True.
-
- The analysis is incomplete because it will find some values unequal when
- actually they are equal.
-
- The analysis is both incomplete and unsound because it expects that
- assignments will always be made by means of the same syntax.
- """
-
- __implements__ = (IAstroidChecker,)
-
- name = "pointless class attribute override checker"
- msgs = {
- "W9951":
- (
- "Assignment to class attribute %s overrides identical assignment in ancestor %s.",
- "pointless-class-attribute-override",
- "Assignment to class attribute that overrides assignment in ancestor that assigns identical value has no effect."
- ),
- "W9952":
- (
- "Definition of %s method overrides identical method definition in ancestor %s.",
- "pointless-method-definition-override",
- "Overriding empty method definition with another empty method definition has no effect."
- )
- }
-
- @check_messages("W9951", "W9952")
- def visit_class(self, node):
- for checker in (PointlessAssignment, PointlessFunctionDefinition):
- for (name, value) in checker.get_data(node):
- for a in node.ancestors():
- match = next((v for (n, v) in checker.get_data(a, False) if n == name), None)
- if match is not None:
- if checker.check_equal(value, match):
- self.add_message(checker.message_id, node=value, args=(name,a.name))
- break
-
-def register(linter):
- linter.register_checker(PointlessClassAttributeOverrideChecker(linter))
diff --git a/tests/pylint/pylint-false-positives b/tests/pylint/pylint-false-positives
deleted file mode 100644
index 9037510..0000000
--- a/tests/pylint/pylint-false-positives
+++ /dev/null
@@ -1,28 +0,0 @@
-^(blivet|tests)/.*: \[E1101\(no-member\).*\] Instance of 'int' has no .* member
-^blivet/.*: \[E0611\(no\-name\-in\-module\).*\] No name 'blockdev' in module 'gi.repository'$
-^blivet/.*: \[E0712\(catching\-non\-exception\).*\] Catching an exception which doesn't inherit from BaseException: (BlockDev|DM|Crypto|Swap|LVM|Btrfs|MDRaid|)Error$
-^blivet/.*: \[E0712\(catching\-non\-exception\).*\] Catching an exception which doesn't inherit from BaseException: GError$
-^blivet/__init__.py:[[:digit:]]+: \[W0602\(global\-variable\-not\-assigned\), enable_installer_mode\] Using global for 'BootLoaderError' but no assignment is done$
-^blivet/__init__.py:[[:digit:]]+: \[W0602\(global\-variable\-not\-assigned\), enable_installer_mode\] Using global for 'ERROR_RAISE' but no assignment is done$
-^blivet/__init__.py:[[:digit:]]+: \[W0602\(global\-variable\-not\-assigned\), enable_installer_mode\] Using global for 'ROOT_PATH' but no assignment is done$
-^blivet/__init__.py:[[:digit:]]+: \[W0602\(global\-variable\-not\-assigned\), enable_installer_mode\] Using global for 'errorHandler' but no assignment is done$
-^blivet/__init__.py:[[:digit:]]+: \[W0602\(global\-variable\-not\-assigned\), enable_installer_mode\] Using global for 'get_bootloader' but no assignment is done$
-^blivet/__init__.py:[[:digit:]]+: \[W0602\(global\-variable\-not\-assigned\), enable_installer_mode\] Using global for 'isys' but no assignment is done$
-^blivet/__init__.py:[[:digit:]]+: \[W0602\(global\-variable\-not\-assigned\), enable_installer_mode\] Using global for 'iutil' but no assignment is done$
-^blivet/__init__.py:[[:digit:]]+: \[W0602\(global\-variable\-not\-assigned\), enable_installer_mode\] Using global for 'productName' but no assignment is done$
-^blivet/__init__.py:[[:digit:]]+: \[W0602\(global\-variable\-not\-assigned\), enable_installer_mode\] Using global for 'shortProductName' but no assignment is done$
-^blivet/__init__.py:[[:digit:]]+: \[W0612\(unused\-variable\), enable_installer_mode\] Unused variable 'ERROR_RAISE'$
-^blivet/__init__.py:[[:digit:]]+: \[W0612\(unused\-variable\), enable_installer_mode\] Unused variable 'ROOT_PATH'$
-^blivet/__init__.py:[[:digit:]]+: \[W0612\(unused\-variable\), enable_installer_mode\] Unused variable 'errorHandler'$
-^blivet/__init__.py:[[:digit:]]+: \[W0612\(unused\-variable\), enable_installer_mode\] Unused variable 'get_bootloader'$
-^blivet/__init__.py:[[:digit:]]+: \[W0612\(unused\-variable\), enable_installer_mode\] Unused variable 'isys'$
-^blivet/__init__.py:[[:digit:]]+: \[W0612\(unused\-variable\), enable_installer_mode\] Unused variable 'productName'$
-^blivet/__init__.py:[[:digit:]]+: \[W0612\(unused\-variable\), enable_installer_mode\] Unused variable 'shortProductName'$
-^blivet/arch.py:[[:digit:]]+: \[F0401\(import\-error\), numBits\] Unable to import 'platform'$
-^blivet/blivet.py:[[:digit:]]+: \[E1101\(no\-member\), Blivet.savePassphrase\] Instance of 'DeviceTree' has no '_DeviceTree__luksDevs' member$
-^blivet/blivet.py:[[:digit:]]+: \[E1101\(no\-member\), Blivet.savePassphrase\] Instance of 'DeviceTree' has no '_DeviceTree__passphrases' member$
-^blivet/formats/__init__.py:[[:digit:]]+: \[W0201\(attribute\-defined\-outside\-init\), DeviceFormat._setDevice\] Attribute '_device' defined outside __init__$
-^dm.c: [[:digit:]]+: not running as root returning empty list$
-^tests/devicelibs_test/mdraid_test.py:[[:digit:]]+: \[E1003\(bad\-super\-call\), ([[:alnum:]\.]+).__init__\] Bad first argument YES given to super\(\)$
-^tests/devicelibs_test/raid_test.py:[[:digit:]]+: \[E1120\(no\-value\-for\-parameter\), [[:alnum:]\.]+\] No value [[:alnum:] ]+ 'member_count' in [[:alnum:] ]+ call$
-^tests/devicelibs_test/raid_test.py:[[:digit:]]+: \[E1120\(no\-value\-for\-parameter\), [[:alnum:]\.]+\] No value [[:alnum:] ]+ 'smallest_member_size' in [[:alnum:] ]+ call$
diff --git a/tests/pylint/pylint-one.sh b/tests/pylint/pylint-one.sh
deleted file mode 100755
index 9b1e79b..0000000
--- a/tests/pylint/pylint-one.sh
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/bash
-#
-# $1 -- python source to run pylint on
-#
-
-if [ $# -lt 1 ]; then
- # no source, just exit
- exit 1
-fi
-
-file_suffix="$(eval echo \$$#|sed s?/?_?g)"
-
-pylint_output="$(pylint \
- --msg-template='{path}:{line}: [{msg_id}({symbol}), {obj}] {msg}' \
- -r n --disable=C,R --rcfile=/dev/null \
- --dummy-variables-rgx=_ \
- --ignored-classes=Popen,TransactionSet \
- --defining-attr-methods=__init__,_grabObjects,initialize,reset,start,setUp \
- --load-plugins=intl,pointless-override \
- $DISABLED_WARN_OPTIONS \
- $DISABLED_ERR_OPTIONS \
- $NON_STRICT_OPTIONS "$@" 2>&1 | \
- egrep -v -f "$FALSE_POSITIVES" \
- )"
-
-# I0011 is the informational "Locally disabling ...." message
-if [ -n "$(echo "$pylint_output" | fgrep -v '************* Module ' |\
- grep -v '^I0011:')" ]; then
- # Replace the Module line with the actual filename
- pylint_output="$(echo "$pylint_output" | sed "s|\* Module .*|* Module $(eval echo \$$#)|")"
- echo "$pylint_output" > pylint-out_$file_suffix
- touch "pylint-$file_suffix-failed"
-fi
diff --git a/tests/pylint/runpylint.py b/tests/pylint/runpylint.py
new file mode 100755
index 0000000..859c3ea
--- /dev/null
+++ b/tests/pylint/runpylint.py
@@ -0,0 +1,34 @@
+#!/usr/bin/python3
+
+import os
+
+from pocketlint import FalsePositive, PocketLintConfig, PocketLinter
+
+class BlivetLintConfig(PocketLintConfig):
+ def __init__(self):
+ PocketLintConfig.__init__(self)
+
+ self.falsePositives = [ FalsePositive(r"Catching an exception which doesn't inherit from BaseException: (BlockDev|DM|Crypto|Swap|LVM|Btrfs|MDRaid|)Error$"),
+ FalsePositive(r"Instance of 'int' has no .* member$"),
+ FalsePositive(r"No value for argument 'member_count' in unbound method call$"),
+ FalsePositive(r"No value for argument 'smallest_member_size' in unbound method call$"),
+ ]
+
+ @property
+ def disabledOptions(self):
+ return [ "W0105", # String statement has no effect
+ "W0110", # map/filter on lambda could be replaced by comprehension
+ "W0141", # Used builtin function %r
+ "W0142", # Used * or ** magic
+ "W0212", # Access to a protected member of a client class
+ "W0511", # Used when a warning note as FIXME or XXX is detected.
+ "W0603", # Using the global statement
+ "W0614", # Unused import %s from wildcard import
+ "I0011", # Locally disabling %s
+ ]
+
+if __name__ == "__main__":
+ conf = BlivetLintConfig()
+ linter = PocketLinter(conf)
+ rc = linter.run()
+ os._exit(rc)
diff --git a/tests/pylint/runpylint.sh b/tests/pylint/runpylint.sh
deleted file mode 100755
index 18200bf..0000000
--- a/tests/pylint/runpylint.sh
+++ /dev/null
@@ -1,125 +0,0 @@
-#!/bin/bash
-
-# This script will check for any pylint warning and errors using a set
-# of options minimizing false positives, in combination with filtering of any
-# warning regularexpressions listed in pylint-false-positives.
-#
-# If any warnings are found they will be stored in pylint-log and printed
-# to stdout and this script will exit with a status of 1, if no (non filtered)
-# warnings are found it exits with a status of 0
-
-# If $top_srcdir is set, assume this is being run from automake and we don't
-# need to keep a separate log
-export pylint_log=0
-if [ -z "$top_srcdir" ]; then
- export pylint_log=1
-fi
-
-# Unset TERM so that things that use readline don't output terminal garbage
-unset TERM
-
-# Don't try to connect to the accessibility socket
-export NO_AT_BRIDGE=1
-
-# If $top_srcdir has not been set by automake, import the test environment
-if [ -z "$top_srcdir" ]; then
- top_srcdir="$(dirname "$0")/../.."
- . ${top_srcdir}/tests/testenv.sh
-fi
-
-. ${top_srcdir}/tests/lib/testlib.sh
-
-srcdir="${top_srcdir}/tests/pylint"
-builddir="${top_builddir}/tests/pylint"
-
-# Need to add the pylint module directory to PYTHONPATH as well.
-export PYTHONPATH="${PYTHONPATH}:${srcdir}"
-
-# Save analysis data in the pylint directory
-export PYLINTHOME="${builddir}/.pylint.d"
-[ -d "$PYLINTHOME" ] || mkdir "$PYLINTHOME"
-
-export FALSE_POSITIVES="${srcdir}"/pylint-false-positives
-
-# W0212 - Access to a protected member %s of a client class
-export NON_STRICT_OPTIONS="--disable=W0212"
-
-# E1103 - %s %r has no %r member (but some types could not be inferred)
-export DISABLED_ERR_OPTIONS="--disable=E1103"
-
-# W0105 - String statement has no effect
-# W0110 - map/filter on lambda could be replaced by comprehension
-# W0141 - Used builtin function %r
-# W0142 - Used * or ** magic
-# W0511 - Used when a warning note as FIXME or XXX is detected.
-# W0603 - Using the global statement
-# W0614 - Unused import %s from wildcard import
-# I0011 - Locally disabling %s (i.e., pylint: disable)
-export DISABLED_WARN_OPTIONS="--disable=W0105,W0110,W0141,W0142,W0511,W0603,W0614,I0011"
-
-usage () {
- echo "usage: `basename $0` [--strict] [--help] [files...]"
- exit $1
-}
-
-# Separate the module parameters from the files list
-ARGS=
-FILES=
-while [ $# -gt 0 ]; do
- case $1 in
- --strict)
- export NON_STRICT_OPTIONS=
- ;;
- --help)
- usage 0
- ;;
- -*)
- ARGS="$ARGS $1"
- ;;
- *)
- FILES=$@
- break
- esac
- shift
-done
-
-exit_status=0
-
-if [ -s pylint-log ]; then
- rm pylint-log
-fi
-
-# run pylint one file / module at a time, otherwise it sometimes gets
-# confused
-if [ -z "$FILES" ]; then
- # Test any file that either ends in .py or contains #!/usr/bin/python in
- # the first line. Scan everything except old_tests
- FILES=$(findtestfiles \( -name '*.py' -o \
- -exec /bin/sh -c "head -1 {} | grep -q '#!/usr/bin/python'" \; \) -print | \
- egrep -v '(|/)doc/conf.py')
-fi
-
-num_cpus=$(getconf _NPROCESSORS_ONLN)
-# run pylint in paralel
-echo $FILES | xargs --max-procs=$num_cpus -n 1 "$srcdir"/pylint-one.sh $ARGS || exit 1
-
-for file in $(find -name 'pylint-out*'); do
- cat "$file" >> pylint-log
- rm "$file"
-done
-
-fails=$(find -name 'pylint*failed' -print -exec rm '{}' \;)
-if [ -z "$fails" ]; then
- exit_status=0
-else
- exit_status=1
-fi
-
-if [ -s pylint-log ]; then
- echo "pylint reports the following issues:"
- cat pylint-log
-elif [ -e pylint-log ]; then
- rm pylint-log
-fi
-
-exit "$exit_status"
--
2.2.2
9 years