Last active
January 13, 2018 07:15
-
-
Save mbdevpl/5e33cb1c23c5d8e011f8e656eb0883a8 to your computer and use it in GitHub Desktop.
Pylint issue - wrong location of too-many-public-methods error
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""Some code causing strange behavior in Pylint.""" | |
import enum | |
import itertools | |
import logging | |
import re | |
import typing as t | |
import packaging.version | |
import pkg_resources | |
import semver | |
_LOG = logging.getLogger(__name__) | |
@enum.unique | |
class VersionComponent(enum.IntEnum): | |
"""Enumeration of standard version components.""" | |
Major = 1 << 1 | |
Minor = 1 << 2 | |
Patch = 1 << 3 | |
Release = Major | Minor | Patch | |
PrePatch = 1 << 4 | |
DevPatch = 1 << 5 | |
Local = 1 << 6 | |
def _version_tuple_checker(version_tuple, flags): | |
return (version_tuple, flags) | |
class Version: | |
"""For storing and manipulating version information.""" | |
_re_number = r'(?:0|[123456789][0123456789]*)' | |
_re_letters = r'(?:[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]+)' | |
_pattern_letters = re.compile(_re_letters) | |
_re_sep = r'(?:[\.-])' | |
@classmethod | |
def _parse_release_str(cls, release: str) -> tuple: | |
return cls._pattern_letters.fullmatch(release) | |
@classmethod | |
def _parse_pre_release_str(cls, pre_release: str) -> tuple: | |
parts = cls._pattern_letters.findall(pre_release) | |
_LOG.debug('parsed pre-release string %s into %s', | |
repr(pre_release), parts) | |
tuples = [] | |
return tuples | |
@classmethod | |
def _parse_local_str(cls, local: str) -> tuple: | |
match = cls._pattern_letters.fullmatch(local) | |
return tuple([_ for _ in match.groups() if _ is not None]) | |
@classmethod | |
def from_str(cls, version_str: str): | |
"""Create version from string.""" | |
py_version = pkg_resources.parse_version(version_str) # type: packaging.version.Version | |
_LOG.debug('packaging parsed version string %s into %s: %s', | |
repr(version_str), type(py_version), py_version) | |
return cls() | |
@classmethod | |
def from_tuple(cls, version_tuple: tuple): | |
return cls(*version_tuple) | |
@classmethod | |
def from_dict(cls, version_dict: dict): | |
return cls(**version_dict) | |
@classmethod | |
def from_py_version( | |
cls, py_version: t.Union[packaging.version.Version, pkg_resources.SetuptoolsVersion]): | |
"""Create version from a standard Python version object.""" | |
raise NotImplementedError(type(py_version)) | |
@classmethod | |
def from_sem_version(cls, sem_version: t.Union[dict, semver.VersionInfo]): | |
"""Create version from semantic version object.""" | |
_LOG.debug('parsing %s %s', type(sem_version), sem_version) | |
return cls() | |
@classmethod | |
def from_version(cls, version: 'Version'): | |
return cls.from_dict(version.to_dict()) | |
def __init__( | |
self): | |
self._major = None | |
self._minor = None | |
self._patch = None | |
self._pre_release = None | |
self._local = None | |
@property | |
def release(self) -> t.Tuple[int, t.Optional[int], t.Optional[int]]: | |
return self._major, self._minor, self._patch | |
@release.setter | |
def release(self, release: t.Tuple[int, t.Optional[int], t.Optional[int]]): | |
major, minor, patch = release | |
self._major = major | |
self._minor = minor | |
self._patch = patch | |
@property | |
def pre_release(self): | |
return self._pre_release.copy() | |
@pre_release.setter | |
def pre_release(self, pre_release): | |
self._pre_release = pre_release | |
@property | |
def has_pre_release(self): | |
return self._pre_release is not None | |
@property | |
def local(self) -> t.Optional[t.Sequence[str]]: | |
return self._local | |
@local.setter | |
def local(self, local: t.Optional[t.Sequence[str]]): | |
if local is None: | |
self._local = None | |
return | |
self._local = tuple(local) | |
@property | |
def has_local(self): | |
return self._local is not None | |
def increment(self, component: VersionComponent, amount: int = 1) -> 'Version': | |
"""Increment a selected version component and return self.""" | |
if not isinstance(component, VersionComponent): | |
raise TypeError('component={} is of wrong type {}' | |
.format(repr(component), type(component))) | |
if not isinstance(amount, int): | |
raise TypeError('amount={} is of wrong type {}'.format(repr(amount), type(amount))) | |
if amount < 1: | |
raise ValueError('amount={} has wrong value'.format(amount)) | |
return self | |
def devel_increment(self, new_commits: int = 1) -> 'Version': | |
"""Increment version.""" | |
if not self.has_pre_release or self.pre_release_to_tuple(True)[-1][1] != 'dev': | |
self.increment(VersionComponent.Patch) | |
self.increment(VersionComponent.DevPatch, new_commits) | |
return self | |
def release_to_str(self) -> str: | |
"""Get string representation of this version's release component.""" | |
version_tuple = self._major, self._minor, self._patch | |
if version_tuple: | |
raise ValueError('') | |
def _pre_release_segment_to_str(self, segment: int) -> str: | |
version_tuple = self._pre_release[segment] | |
if version_tuple: | |
raise ValueError('') | |
def pre_release_to_str(self) -> str: | |
if self._pre_release is None: | |
return '' | |
return ''.join(self._pre_release_segment_to_str(i) | |
for i, _ in enumerate(self._pre_release)) | |
def local_to_str(self) -> str: | |
return self._local | |
def to_str(self) -> str: | |
return self.release_to_str() | |
def release_to_tuple(self, sort: bool = False) -> tuple: | |
return 0 if sort else self._major | |
def pre_release_segment_to_tuple(self, segment: int, sort: bool = False) -> tuple: | |
pre_separator, pre_type, pre_patch = self._pre_release[segment] | |
return (1 if pre_type is None else 0) if sort else pre_separator, \ | |
('' if pre_type is None else pre_type.lower()) if sort else pre_type, \ | |
(0 if sort else None) if pre_patch is None else pre_patch | |
def pre_release_to_tuple(self, sort: bool = False) -> tuple: | |
"""Create tuple from this version's pre-release component.""" | |
if self._pre_release is None: | |
return ((1, '', 0),) if sort else () | |
parts = [self.pre_release_segment_to_tuple(i, sort) | |
for i, _ in enumerate(self._pre_release)] | |
return tuple(parts) if sort else tuple(itertools.chain.from_iterable(parts)) | |
def local_to_tuple(self, sort: bool = False) -> tuple: | |
return () if sort else self._local | |
def to_tuple(self, sort: bool = False) -> tuple: | |
return self.release_to_tuple(sort) | |
def to_dict(self) -> dict: | |
return {field[1:]: value for field, value in vars(self).items()} | |
def to_py_version(self) -> packaging.version.Version: | |
return pkg_resources.parse_version(self.to_str()) | |
def to_sem_version(self) -> dict: | |
return semver.parse(self.to_str()) | |
def __repr__(self): | |
return '{}({})'.format(type(self).__name__, ', '.join( | |
'{}: {}'.format(field[1:], repr(value)) for field, value in vars(self).items())) | |
def __str__(self): | |
return self.to_str() | |
def __lt__(self, other): | |
if not isinstance(other, Version): | |
return False | |
return False | |
def __eq__(self, other): | |
return not self < other and not other < self | |
def __ne__(self, other): | |
return self < other or other < self | |
def __gt__(self, other): | |
return other < self | |
def __ge__(self, other): | |
return not self < other | |
def __le__(self, other): | |
return not other < self |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""Some code causing strange behavior in Pylint.""" | |
import enum | |
import itertools | |
import logging | |
import re | |
import typing as t | |
import packaging.version | |
import pkg_resources | |
import semver | |
_LOG = logging.getLogger(__name__) | |
@enum.unique | |
class VersionComponent(enum.IntEnum): | |
"""Enumeration of standard version components.""" | |
Major = 1 << 1 | |
Minor = 1 << 2 | |
Patch = 1 << 3 | |
Release = Major | Minor | Patch | |
PrePatch = 1 << 4 | |
DevPatch = 1 << 5 | |
Local = 1 << 6 | |
def _version_tuple_checker(version_tuple, flags): | |
return (version_tuple, flags) | |
class Version: | |
"""For storing and manipulating version information.""" | |
_re_number = r'(?:0|[123456789][0123456789]*)' | |
_re_letters = r'(?:[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]+)' | |
_pattern_letters = re.compile(_re_letters) | |
_re_sep = r'(?:[\.-])' | |
@classmethod | |
def _parse_release_str(cls, release: str) -> tuple: | |
return cls._pattern_letters.fullmatch(release) | |
@classmethod | |
def _parse_pre_release_str(cls, pre_release: str) -> tuple: | |
parts = cls._pattern_letters.findall(pre_release) | |
_LOG.debug('parsed pre-release string %s into %s', | |
repr(pre_release), parts) | |
tuples = [] | |
return tuples | |
@classmethod | |
def _parse_local_str(cls, local: str) -> tuple: | |
match = cls._pattern_letters.fullmatch(local) | |
return tuple([_ for _ in match.groups() if _ is not None]) | |
@classmethod | |
def from_str(cls, version_str: str): | |
"""Create version from string.""" | |
py_version = pkg_resources.parse_version(version_str) # type: packaging.version.Version | |
_LOG.debug('packaging parsed version string %s into %s: %s', | |
repr(version_str), type(py_version), py_version) | |
return cls() | |
@classmethod | |
def from_tuple(cls, version_tuple: tuple): | |
return cls(*version_tuple) | |
@classmethod | |
def from_dict(cls, version_dict: dict): | |
return cls(**version_dict) | |
@classmethod | |
def from_py_version( | |
cls, py_version: t.Union[packaging.version.Version, pkg_resources.SetuptoolsVersion]): | |
"""Create version from a standard Python version object.""" | |
raise NotImplementedError(type(py_version)) | |
@classmethod | |
def from_sem_version(cls, sem_version: t.Union[dict, semver.VersionInfo]): | |
"""Create version from semantic version object.""" | |
_LOG.debug('parsing %s %s', type(sem_version), sem_version) | |
return cls() | |
@classmethod | |
def from_version(cls, version: 'Version'): | |
return cls.from_dict(version.to_dict()) | |
def __init__( | |
self): | |
self._major = None | |
self._minor = None | |
self._patch = None | |
self._pre_release = None | |
self._local = None | |
@property | |
def release(self) -> t.Tuple[int, t.Optional[int], t.Optional[int]]: | |
return self._major, self._minor, self._patch | |
@release.setter | |
def release(self, release: t.Tuple[int, t.Optional[int], t.Optional[int]]): | |
major, minor, patch = release | |
self._major = major | |
self._minor = minor | |
self._patch = patch | |
@property | |
def pre_release(self): | |
return self._pre_release.copy() | |
@pre_release.setter | |
def pre_release(self, pre_release): | |
self._pre_release = pre_release | |
@property | |
def has_pre_release(self): | |
return self._pre_release is not None | |
@property | |
def local(self) -> t.Optional[t.Sequence[str]]: | |
return self._local | |
@local.setter | |
def local(self, local: t.Optional[t.Sequence[str]]): | |
if local is None: | |
self._local = None | |
return | |
self._local = tuple(local) | |
@property | |
def has_local(self): | |
return self._local is not None | |
def increment(self, component: VersionComponent, amount: int = 1) -> 'Version': | |
"""Increment a selected version component and return self.""" | |
if not isinstance(component, VersionComponent): | |
raise TypeError('component={} is of wrong type {}' | |
.format(repr(component), type(component))) | |
if not isinstance(amount, int): | |
raise TypeError('amount={} is of wrong type {}'.format(repr(amount), type(amount))) | |
if amount < 1: | |
raise ValueError('amount={} has wrong value'.format(amount)) | |
return self | |
def devel_increment(self, new_commits: int = 1) -> 'Version': | |
"""Increment version.""" | |
if not self.has_pre_release or self.pre_release_to_tuple(True)[-1][1] != 'dev': | |
self.increment(VersionComponent.Patch) | |
self.increment(VersionComponent.DevPatch, new_commits) | |
return self | |
def release_to_str(self) -> str: | |
"""Get string representation of this version's release component.""" | |
version_tuple = self._major, self._minor, self._patch | |
if version_tuple: | |
raise ValueError('') | |
def _pre_release_segment_to_str(self, segment: int) -> str: | |
version_tuple = self._pre_release[segment] | |
if version_tuple: | |
raise ValueError('') | |
def pre_release_to_str(self) -> str: | |
if self._pre_release is None: | |
return '' | |
return ''.join(self._pre_release_segment_to_str(i) | |
for i, _ in enumerate(self._pre_release)) | |
def local_to_str(self) -> str: | |
return self._local | |
def to_str(self) -> str: | |
return self.release_to_str() | |
def release_to_tuple(self, sort: bool = False) -> tuple: | |
return 0 if sort else self._major | |
def pre_release_segment_to_tuple(self, segment: int, sort: bool = False) -> tuple: | |
pre_separator, pre_type, pre_patch = self._pre_release[segment] | |
return (1 if pre_type is None else 0) if sort else pre_separator, \ | |
('' if pre_type is None else pre_type.lower()) if sort else pre_type, \ | |
(0 if sort else None) if pre_patch is None else pre_patch | |
def pre_release_to_tuple(self, sort: bool = False) -> tuple: | |
"""Create tuple from this version's pre-release component.""" | |
if self._pre_release is None: | |
return ((1, '', 0),) if sort else () | |
parts = [self.pre_release_segment_to_tuple(i, sort) | |
for i, _ in enumerate(self._pre_release)] | |
return tuple(parts) if sort else tuple(itertools.chain.from_iterable(parts)) | |
def local_to_tuple(self, sort: bool = False) -> tuple: | |
return () if sort else self._local | |
def to_tuple(self, sort: bool = False) -> tuple: | |
return self.release_to_tuple(sort) | |
def to_dict(self) -> dict: | |
return {field[1:]: value for field, value in vars(self).items()} | |
def to_py_version(self) -> packaging.version.Version: | |
return pkg_resources.parse_version(self.to_str()) | |
def to_sem_version(self) -> dict: | |
return semver.parse(self.to_str()) | |
#def __repr__(self): | |
# return '{}({})'.format(type(self).__name__, ', '.join( | |
# '{}: {}'.format(field[1:], repr(value)) for field, value in vars(self).items())) | |
def __str__(self): | |
return self.to_str() | |
def __lt__(self, other): | |
if not isinstance(other, Version): | |
return False | |
return False | |
def __eq__(self, other): | |
return not self < other and not other < self | |
def __ne__(self, other): | |
return self < other or other < self | |
def __gt__(self, other): | |
return other < self | |
def __ge__(self, other): | |
return not self < other | |
def __le__(self, other): | |
return not other < self |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ pylint --reports=n pylint_wrong_error_loc.py | |
No config file found, using default configuration | |
************* Module version | |
C: 70, 4: Missing method docstring (missing-docstring) | |
C: 74, 4: Missing method docstring (missing-docstring) | |
C: 90, 4: Missing method docstring (missing-docstring) | |
C:102, 4: Missing method docstring (missing-docstring) | |
C:113, 4: Missing method docstring (missing-docstring) | |
C:121, 4: Missing method docstring (missing-docstring) | |
C:125, 4: Missing method docstring (missing-docstring) | |
C:137, 4: Missing method docstring (missing-docstring) | |
C:172, 4: Missing method docstring (missing-docstring) | |
C:178, 4: Missing method docstring (missing-docstring) | |
C:181, 4: Missing method docstring (missing-docstring) | |
C:184, 4: Missing method docstring (missing-docstring) | |
C:187, 4: Missing method docstring (missing-docstring) | |
C:201, 4: Missing method docstring (missing-docstring) | |
C:204, 4: Missing method docstring (missing-docstring) | |
C:207, 4: Missing method docstring (missing-docstring) | |
C:210, 4: Missing method docstring (missing-docstring) | |
C:213, 4: Missing method docstring (missing-docstring) | |
R: 34,31: Too many public methods (25/20) (too-many-public-methods) | |
------------------------------------------------------------------ | |
Your code has been rated at 8.68/10 (previous run: 8.68/10, +0.00) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ pylint --reports=n version.py | |
No config file found, using default configuration | |
************* Module version | |
C: 70, 4: Missing method docstring (missing-docstring) | |
C: 74, 4: Missing method docstring (missing-docstring) | |
C: 90, 4: Missing method docstring (missing-docstring) | |
C:102, 4: Missing method docstring (missing-docstring) | |
C:113, 4: Missing method docstring (missing-docstring) | |
C:121, 4: Missing method docstring (missing-docstring) | |
C:125, 4: Missing method docstring (missing-docstring) | |
C:137, 4: Missing method docstring (missing-docstring) | |
C:172, 4: Missing method docstring (missing-docstring) | |
C:178, 4: Missing method docstring (missing-docstring) | |
C:181, 4: Missing method docstring (missing-docstring) | |
C:184, 4: Missing method docstring (missing-docstring) | |
C:187, 4: Missing method docstring (missing-docstring) | |
C:201, 4: Missing method docstring (missing-docstring) | |
C:204, 4: Missing method docstring (missing-docstring) | |
C:207, 4: Missing method docstring (missing-docstring) | |
C:210, 4: Missing method docstring (missing-docstring) | |
C:213, 4: Missing method docstring (missing-docstring) | |
R: 34, 0: Too many public methods (25/20) (too-many-public-methods) | |
------------------------------------------------------------------ | |
Your code has been rated at 8.66/10 (previous run: 8.66/10, +0.00) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment