Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Truncate output of invalid-slots-object message for classes #6101

Closed
jacobtylerwalls opened this issue Apr 1, 2022 · 2 comments · Fixed by #6192
Closed

Truncate output of invalid-slots-object message for classes #6101

jacobtylerwalls opened this issue Apr 1, 2022 · 2 comments · Fixed by #6192
Labels
Good first issue Friendly and approachable by new contributors Maintenance Discussion or action around maintaining pylint or the dev workflow Minor 💅 Polishing pylint is always nice
Milestone

Comments

@jacobtylerwalls
Copy link
Member

Bug description

Same test case from #6100, but not regarding the crash in redefined-slots-in-subclass. This is regarding the verbose output for the invalid-slots-object message, which might print the entire content of a class.

class MyClass:
    __slots__ = [str]

Configuration

No response

Command used

pylint a.py

Pylint output

************* Module a
/Users/.../a.py:2:17: E0236: Invalid object '\n\nclass str(object):\n    """str(object=\'\') -> str\nstr(bytes_or_buffer[, encoding[, errors]]) -> str\n\nCreate a new string object from the given object. If encoding or\nerrors is specified, then the object must expose a data buffer\nthat will be decoded using the given encoding and error handler.\nOtherwise, returns the result of object.__str__() (if defined)\nor repr(object).\nencoding defaults to sys.getdefaultencoding().\nerrors defaults to \'strict\'."""\n    \n    def __add__():\n        """Return self+value."""\n        \n    \n    def __contains__():\n        """Return key in self."""\n        \n    \n    def __delattr__():\n        """Implement delattr(self, name)."""\n        \n    \n    def __dir__():\n        """Default dir() implementation."""\n        \n    \n    def __eq__():\n        """Return self==value."""\n        \n    \n    def __format__():\n        """Return a formatted version of the string as described by format_spec."""\n        \n    \n    def __ge__():\n        """Return self>=value."""\n        \n    \n    def __getattribute__():\n        """Return getattr(self, name)."""\n        \n    \n    def __getitem__():\n        """Return self[key]."""\n        \n    \n    def __getnewargs__():\n        \n    \n    def __gt__():\n        """Return self>value."""\n        \n    \n    def __hash__():\n        """Return hash(self)."""\n        \n    \n    def __init__():\n        """Initialize self.  See help(type(self)) for accurate signature."""\n        \n    \n    def __iter__():\n        """Implement iter(self)."""\n        \n    \n    def __le__():\n        """Return self<=value."""\n        \n    \n    def __len__():\n        """Return len(self)."""\n        \n    \n    def __lt__():\n        """Return self<value."""\n        \n    \n    def __mod__():\n        """Return self%value."""\n        \n    \n    def __mul__():\n        """Return self*value."""\n        \n    \n    def __ne__():\n        """Return self!=value."""\n        \n    \n    def __new__():\n        """Create and return a new object.  See help(type) for accurate signature."""\n        \n    \n    def __reduce__():\n        """Helper for pickle."""\n        \n    \n    def __reduce_ex__():\n        """Helper for pickle."""\n        \n    \n    def __repr__():\n        """Return repr(self)."""\n        \n    \n    def __rmod__():\n        """Return value%self."""\n        \n    \n    def __rmul__():\n        """Return value*self."""\n        \n    \n    def __setattr__():\n        """Implement setattr(self, name, value)."""\n        \n    \n    def __sizeof__():\n        """Return the size of the string in memory, in bytes."""\n        \n    \n    def __str__():\n        """Return str(self)."""\n        \n    \n    def __subclasshook__():\n        """Abstract classes can override this to customize issubclass().\n\nThis is invoked early on by abc.ABCMeta.__subclasscheck__().\nIt should return True, False or NotImplemented.  If it returns\nNotImplemented, the normal algorithm is used.  Otherwise, it\noverrides the normal algorithm (and the outcome is cached).\n"""\n        \n    \n    def capitalize():\n        """Return a capitalized version of the string.\n\nMore specifically, make the first character have upper case and the rest lower\ncase."""\n        \n    \n    def casefold():\n        """Return a version of the string suitable for caseless comparisons."""\n        \n    \n    def center():\n        """Return a centered string of length width.\n\nPadding is done using the specified fill character (default is a space)."""\n        \n    \n    def count():\n        """S.count(sub[, start[, end]]) -> int\n\nReturn the number of non-overlapping occurrences of substring sub in\nstring S[start:end].  Optional arguments start and end are\ninterpreted as in slice notation."""\n        \n    \n    def encode():\n        """Encode the string using the codec registered for encoding.\n\n  encoding\n    The encoding in which to encode the string.\n  errors\n    The error handling scheme to use for encoding errors.\n    The default is \'strict\' meaning that encoding errors raise a\n    UnicodeEncodeError.  Other possible values are \'ignore\', \'replace\' and\n    \'xmlcharrefreplace\' as well as any other name registered with\n    codecs.register_error that can handle UnicodeEncodeErrors."""\n        \n    \n    def endswith():\n        """S.endswith(suffix[, start[, end]]) -> bool\n\nReturn True if S ends with the specified suffix, False otherwise.\nWith optional start, test S beginning at that position.\nWith optional end, stop comparing S at that position.\nsuffix can also be a tuple of strings to try."""\n        \n    \n    def expandtabs():\n        """Return a copy where all tab characters are expanded using spaces.\n\nIf tabsize is not given, a tab size of 8 characters is assumed."""\n        \n    \n    def find():\n        """S.find(sub[, start[, end]]) -> int\n\nReturn the lowest index in S where substring sub is found,\nsuch that sub is contained within S[start:end].  Optional\narguments start and end are interpreted as in slice notation.\n\nReturn -1 on failure."""\n        \n    \n    def format():\n        """S.format(*args, **kwargs) -> str\n\nReturn a formatted version of S, using substitutions from args and kwargs.\nThe substitutions are identified by braces (\'{\' and \'}\')."""\n        \n    \n    def format_map():\n        """S.format_map(mapping) -> str\n\nReturn a formatted version of S, using substitutions from mapping.\nThe substitutions are identified by braces (\'{\' and \'}\')."""\n        \n    \n    def index():\n        """S.index(sub[, start[, end]]) -> int\n\nReturn the lowest index in S where substring sub is found,\nsuch that sub is contained within S[start:end].  Optional\narguments start and end are interpreted as in slice notation.\n\nRaises ValueError when the substring is not found."""\n        \n    \n    def isalnum():\n        """Return True if the string is an alpha-numeric string, False otherwise.\n\nA string is alpha-numeric if all characters in the string are alpha-numeric and\nthere is at least one character in the string."""\n        \n    \n    def isalpha():\n        """Return True if the string is an alphabetic string, False otherwise.\n\nA string is alphabetic if all characters in the string are alphabetic and there\nis at least one character in the string."""\n        \n    \n    def isascii():\n        """Return True if all characters in the string are ASCII, False otherwise.\n\nASCII characters have code points in the range U+0000-U+007F.\nEmpty string is ASCII too."""\n        \n    \n    def isdecimal():\n        """Return True if the string is a decimal string, False otherwise.\n\nA string is a decimal string if all characters in the string are decimal and\nthere is at least one character in the string."""\n        \n    \n    def isdigit():\n        """Return True if the string is a digit string, False otherwise.\n\nA string is a digit string if all characters in the string are digits and there\nis at least one character in the string."""\n        \n    \n    def isidentifier():\n        """Return True if the string is a valid Python identifier, False otherwise.\n\nCall keyword.iskeyword(s) to test whether string s is a reserved identifier,\nsuch as "def" or "class"."""\n        \n    \n    def islower():\n        """Return True if the string is a lowercase string, False otherwise.\n\nA string is lowercase if all cased characters in the string are lowercase and\nthere is at least one cased character in the string."""\n        \n    \n    def isnumeric():\n        """Return True if the string is a numeric string, False otherwise.\n\nA string is numeric if all characters in the string are numeric and there is at\nleast one character in the string."""\n        \n    \n    def isprintable():\n        """Return True if the string is printable, False otherwise.\n\nA string is printable if all of its characters are considered printable in\nrepr() or if it is empty."""\n        \n    \n    def isspace():\n        """Return True if the string is a whitespace string, False otherwise.\n\nA string is whitespace if all characters in the string are whitespace and there\nis at least one character in the string."""\n        \n    \n    def istitle():\n        """Return True if the string is a title-cased string, False otherwise.\n\nIn a title-cased string, upper- and title-case characters may only\nfollow uncased characters and lowercase characters only cased ones."""\n        \n    \n    def isupper():\n        """Return True if the string is an uppercase string, False otherwise.\n\nA string is uppercase if all cased characters in the string are uppercase and\nthere is at least one cased character in the string."""\n        \n    \n    def join():\n        """Concatenate any number of strings.\n\nThe string whose method is called is inserted in between each given string.\nThe result is returned as a new string.\n\nExample: \'.\'.join([\'ab\', \'pq\', \'rs\']) -> \'ab.pq.rs\'"""\n        \n    \n    def ljust():\n        """Return a left-justified string of length width.\n\nPadding is done using the specified fill character (default is a space)."""\n        \n    \n    def lower():\n        """Return a copy of the string converted to lowercase."""\n        \n    \n    def lstrip():\n        """Return a copy of the string with leading whitespace removed.\n\nIf chars is given and not None, remove characters in chars instead."""\n        \n    \n    def partition():\n        """Partition the string into three parts using the given separator.\n\nThis will search for the separator in the string.  If the separator is found,\nreturns a 3-tuple containing the part before the separator, the separator\nitself, and the part after it.\n\nIf the separator is not found, returns a 3-tuple containing the original string\nand two empty strings."""\n        \n    \n    def removeprefix():\n        """Return a str with the given prefix string removed if present.\n\nIf the string starts with the prefix string, return string[len(prefix):].\nOtherwise, return a copy of the original string."""\n        \n    \n    def removesuffix():\n        """Return a str with the given suffix string removed if present.\n\nIf the string ends with the suffix string and that suffix is not empty,\nreturn string[:-len(suffix)]. Otherwise, return a copy of the original\nstring."""\n        \n    \n    def replace():\n        """Return a copy with all occurrences of substring old replaced by new.\n\n  count\n    Maximum number of occurrences to replace.\n    -1 (the default value) means replace all occurrences.\n\nIf the optional argument count is given, only the first count occurrences are\nreplaced."""\n        \n    \n    def rfind():\n        """S.rfind(sub[, start[, end]]) -> int\n\nReturn the highest index in S where substring sub is found,\nsuch that sub is contained within S[start:end].  Optional\narguments start and end are interpreted as in slice notation.\n\nReturn -1 on failure."""\n        \n    \n    def rindex():\n        """S.rindex(sub[, start[, end]]) -> int\n\nReturn the highest index in S where substring sub is found,\nsuch that sub is contained within S[start:end].  Optional\narguments start and end are interpreted as in slice notation.\n\nRaises ValueError when the substring is not found."""\n        \n    \n    def rjust():\n        """Return a right-justified string of length width.\n\nPadding is done using the specified fill character (default is a space)."""\n        \n    \n    def rpartition():\n        """Partition the string into three parts using the given separator.\n\nThis will search for the separator in the string, starting at the end. If\nthe separator is found, returns a 3-tuple containing the part before the\nseparator, the separator itself, and the part after it.\n\nIf the separator is not found, returns a 3-tuple containing two empty strings\nand the original string."""\n        \n    \n    def rsplit():\n        """Return a list of the words in the string, using sep as the delimiter string.\n\n  sep\n    The delimiter according which to split the string.\n    None (the default value) means split according to any whitespace,\n    and discard empty strings from the result.\n  maxsplit\n    Maximum number of splits to do.\n    -1 (the default value) means no limit.\n\nSplits are done starting at the end of the string and working to the front."""\n        \n    \n    def rstrip():\n        """Return a copy of the string with trailing whitespace removed.\n\nIf chars is given and not None, remove characters in chars instead."""\n        \n    \n    def split():\n        """Return a list of the words in the string, using sep as the delimiter string.\n\n  sep\n    The delimiter according which to split the string.\n    None (the default value) means split according to any whitespace,\n    and discard empty strings from the result.\n  maxsplit\n    Maximum number of splits to do.\n    -1 (the default value) means no limit."""\n        \n    \n    def splitlines():\n        """Return a list of the lines in the string, breaking at line boundaries.\n\nLine breaks are not included in the resulting list unless keepends is given and\ntrue."""\n        \n    \n    def startswith():\n        """S.startswith(prefix[, start[, end]]) -> bool\n\nReturn True if S starts with the specified prefix, False otherwise.\nWith optional start, test S beginning at that position.\nWith optional end, stop comparing S at that position.\nprefix can also be a tuple of strings to try."""\n        \n    \n    def strip():\n        """Return a copy of the string with leading and trailing whitespace removed.\n\nIf chars is given and not None, remove characters in chars instead."""\n        \n    \n    def swapcase():\n        """Convert uppercase characters to lowercase and lowercase characters to uppercase."""\n        \n    \n    def title():\n        """Return a version of the string where each word is titlecased.\n\nMore specifically, words start with uppercased characters and all remaining\ncased characters have lower case."""\n        \n    \n    def translate():\n        """Replace each character in the string using the given translation table.\n\n  table\n    Translation table, which must be a mapping of Unicode ordinals to\n    Unicode ordinals, strings, or None.\n\nThe table must implement lookup/indexing via __getitem__, for instance a\ndictionary or list.  If this operation raises LookupError, the character is\nleft untouched.  Characters mapped to None are deleted."""\n        \n    \n    def upper():\n        """Return a copy of the string converted to uppercase."""\n        \n    \n    def zfill():\n        """Pad a numeric string with zeros on the left, to fill a field of the given width.\n\nThe string is never truncated."""\n        \n' in __slots__, must contain only non empty strings (invalid-slots-object)

Expected behavior

Either truncate the representation or just print the name of the class.

Pylint version

pylint 2.14.0-dev0
astroid 2.12.0-dev0
Python 3.10.1 (v3.10.1:2cd268a3a9, Dec  6 2021, 14:28:59) [Clang 13.0.0 (clang-1300.0.29.3)]

OS / Environment

No response

Additional dependencies

No response

@jacobtylerwalls jacobtylerwalls added Minor 💅 Polishing pylint is always nice Maintenance Discussion or action around maintaining pylint or the dev workflow labels Apr 1, 2022
@jacobtylerwalls
Copy link
Member Author

If this is the case with other messages then we can generalize a solution or perhaps wontfix it?

@Pierre-Sassoulas
Copy link
Member

I think we should display the name of the class instead of the whole class (like we did for end line / end column in vscode for highlighting).

@jacobtylerwalls jacobtylerwalls added Good first issue Friendly and approachable by new contributors and removed Question labels Apr 1, 2022
@Pierre-Sassoulas Pierre-Sassoulas added this to the 2.14.0 milestone Apr 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Good first issue Friendly and approachable by new contributors Maintenance Discussion or action around maintaining pylint or the dev workflow Minor 💅 Polishing pylint is always nice
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants