diff --git a/pylintrc b/pylintrc index 7822814..7eb78e5 100644 --- a/pylintrc +++ b/pylintrc @@ -1,4 +1,26 @@ -[MASTER] +[MAIN] + +# Analyse import fallback blocks. This can be used to support both Python 2 and +# 3 compatible code, which means that the block might have code that exists +# only in one or another interpreter, leading to false positives when analysed. +analyse-fallback-blocks=no + +# Clear in-memory caches upon conclusion of linting. Useful if running pylint +# in a server-like mode. +clear-cache-post-run=no + +# Load and enable all available extensions. Use --list-extensions to see a list +# all available extensions. +#enable-all-extensions= + +# In error mode, messages with a category besides ERROR or FATAL are +# suppressed, and no reports are done by default. Error mode is compatible with +# disabling specific errors. +#errors-only= + +# Always return a 0 (non-error) status code, even if lint errors are found. +# This is primarily useful in continuous integration scripts. +#exit-zero= # A comma-separated list of package or module names from where C extensions may # be loaded. Extensions are loading into the active Python interpreter and may @@ -16,27 +38,40 @@ extension-pkg-whitelist= # specified are enabled, while categories only check already-enabled messages. fail-on= -# Specify a score threshold to be exceeded before program exits with error. +# Specify a score threshold under which the program will exit with error. fail-under=10.0 +# Interpret the stdin as a python script, whose filename needs to be passed as +# the module_or_package argument. +#from-stdin= + # Files or directories to be skipped. They should be base names, not paths. ignore=CVS -# Add files or directories matching the regex patterns to the ignore-list. The -# regex matches against paths and can be in Posix or Windows format. +# Add files or directories matching the regular expressions patterns to the +# ignore-list. The regex matches against paths and can be in Posix or Windows +# format. Because '\\' represents the directory delimiter on Windows systems, +# it can't be used as an escape character. ignore-paths= -# Files or directories matching the regex patterns are skipped. The regex -# matches against base names, not paths. The default value ignores emacs file -# locks +# Files or directories matching the regular expression patterns are skipped. +# The regex matches against base names, not paths. The default value ignores +# Emacs file locks ignore-patterns=^\.# +# List of module names for which member attributes should not be checked +# (useful for modules/projects where namespaces are manipulated during runtime +# and thus existing member attributes cannot be deduced by static analysis). It +# supports qualified module names, as well as Unix pattern matching. +ignored-modules= + # Python code to execute, usually for sys.path manipulation such as # pygtk.require(). #init-hook= # Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the -# number of processors available to use. +# number of processors available to use, and will cap the count on Windows to +# avoid hangs. jobs=1 # Control the amount of potential inferred values when inferring a single @@ -66,77 +101,8 @@ suggestion-mode=yes # active Python interpreter and may run arbitrary code. unsafe-load-any-extension=no - -[MESSAGES CONTROL] - -# Only show warnings with the listed confidence levels. Leave empty to show -# all. Valid levels: HIGH, CONTROL_FLOW, INFERENCE, INFERENCE_FAILURE, -# UNDEFINED. -confidence= - -# Disable the message, report, category or checker with the given id(s). You -# can either give multiple identifiers separated by comma (,) or put this -# option multiple times (only on the command line, not in the configuration -# file where it should appear only once). You can also use "--disable=all" to -# disable everything first and then re-enable specific checks. For example, if -# you want to run only the similarities checker, you can use "--disable=all -# --enable=similarities". If you want to run only the classes checker, but have -# no Warning level messages displayed, use "--disable=all --enable=classes -# --disable=W". -disable=raw-checker-failed, - bad-inline-option, - locally-disabled, - file-ignored, - suppressed-message, - useless-suppression, - deprecated-pragma, - use-symbolic-message-instead, - missing-module-docstring, - missing-class-docstring, - missing-function-docstring - -# Enable the message, report, category or checker with the given id(s). You can -# either give multiple identifier separated by comma (,) or put this option -# multiple time (only on the command line, not in the configuration file where -# it should appear only once). See also the "--disable" option for examples. -enable=c-extension-no-member - - -[REPORTS] - -# Python expression which should return a score less than or equal to 10. You -# have access to the variables 'fatal', 'error', 'warning', 'refactor', -# 'convention', and 'info' which contain the number of messages in each -# category, as well as 'statement' which is the total number of statements -# analyzed. This score is used by the global evaluation report (RP0004). -evaluation=max(0, 0 if fatal else 10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)) - -# Template used to display messages. This is a python new-style format string -# used to format the message information. See doc for all details. -#msg-template= - -# Set the output format. Available formats are text, parseable, colorized, json -# and msvs (visual studio). You can also give a reporter class, e.g. -# mypackage.mymodule.MyReporterClass. -output-format=text - -# Tells whether to display a full report or only the messages. -reports=no - -# Activate the evaluation score. -score=yes - - -[REFACTORING] - -# Maximum number of nested blocks for function / method body -max-nested-blocks=5 - -# Complete name of functions that never returns. When checking for -# inconsistent-return-statements if a never returning function is called then -# it will be considered as an explicit return statement and no message will be -# printed. -never-returning-functions=sys.exit,argparse.parse_error +# In verbose mode, extra non-checker-related info will be displayed. +#verbose= [BASIC] @@ -275,74 +241,77 @@ variable-naming-style=snake_case #variable-rgx= -[MISCELLANEOUS] +[CLASSES] -# List of note tags to take in consideration, separated by a comma. -notes=FIXME, - XXX, - TODO +# Warn about protected attribute access inside special methods +check-protected-access-in-special-methods=no -# Regular expression of note tags to take in consideration. -#notes-rgx= +# List of method names used to declare (i.e. assign) instance attributes. +defining-attr-methods=__init__, + __new__, + setUp, + __post_init__ +# List of member names, which should be excluded from the protected access +# warning. +exclude-protected=_asdict, + _fields, + _replace, + _source, + _make -[TYPECHECK] +# List of valid names for the first argument in a class method. +valid-classmethod-first-arg=cls -# List of decorators that produce context managers, such as -# contextlib.contextmanager. Add to this list to register other decorators that -# produce valid context managers. -contextmanager-decorators=contextlib.contextmanager +# List of valid names for the first argument in a metaclass class method. +valid-metaclass-classmethod-first-arg=cls -# List of members which are set dynamically and missed by pylint inference -# system, and so shouldn't trigger E1101 when accessed. Python regular -# expressions are accepted. -generated-members= -# Tells whether missing members accessed in mixin class should be ignored. A -# class is considered mixin if its name matches the mixin-class-rgx option. -ignore-mixin-members=yes +[DESIGN] -# Tells whether to warn about missing members when the owner of the attribute -# is inferred to be None. -ignore-none=yes +# List of regular expressions of class ancestor names to ignore when counting +# public methods (see R0903) +exclude-too-few-public-methods= -# This flag controls whether pylint should warn about no-member and similar -# checks whenever an opaque object is returned when inferring. The inference -# can return multiple potential results while evaluating a Python object, but -# some branches might not be evaluated, which results in partial inference. In -# that case, it might be useful to still emit no-member and other checks for -# the rest of the inferred objects. -ignore-on-opaque-inference=yes +# List of qualified class names to ignore when counting class parents (see +# R0901) +ignored-parents= -# List of class names for which member attributes should not be checked (useful -# for classes with dynamically set attributes). This supports the use of -# qualified names. -ignored-classes=optparse.Values,thread._local,_thread._local +# Maximum number of arguments for function / method. +max-args=10 -# List of module names for which member attributes should not be checked -# (useful for modules/projects where namespaces are manipulated during runtime -# and thus existing member attributes cannot be deduced by static analysis). It -# supports qualified module names, as well as Unix pattern matching. -ignored-modules= +# Maximum number of attributes for a class (see R0902). +max-attributes=10 -# Show a hint with possible names when a member name was not found. The aspect -# of finding the hint is based on edit distance. -missing-member-hint=yes +# Maximum number of boolean expressions in an if statement (see R0916). +max-bool-expr=5 -# The minimum edit distance a name should have in order to be considered a -# similar match for a missing member name. -missing-member-hint-distance=1 +# Maximum number of branch for function / method body. +max-branches=12 -# The total number of similar names that should be taken in consideration when -# showing a hint for a missing member. -missing-member-max-choices=1 +# Maximum number of locals for function / method body. +max-locals=30 -# Regex pattern to define which classes are considered mixins ignore-mixin- -# members is set to 'yes' -mixin-class-rgx=.*[Mm]ixin +# Maximum number of parents for a class (see R0901). +max-parents=7 -# List of decorators that change the signature of a decorated function. -signature-mutators= +# Maximum number of public methods for a class (see R0904). +max-public-methods=25 + +# Maximum number of return / yield for function / method body. +max-returns=20 + +# Maximum number of statements in function / method body. +max-statements=50 + +# Minimum number of public methods for a class (see R0903). +min-public-methods=2 + + +[EXCEPTIONS] + +# Exceptions that will emit a warning when caught. +overgeneral-exceptions=builtins.BaseException,builtins.Exception [FORMAT] @@ -375,33 +344,43 @@ single-line-class-stmt=no single-line-if-stmt=no -[STRING] +[IMPORTS] -# This flag controls whether inconsistent-quotes generates a warning when the -# character used as a quote delimiter is used inconsistently within a module. -check-quote-consistency=no +# List of modules that can be imported at any level, not just the top level +# one. +allow-any-import-level= -# This flag controls whether the implicit-str-concat should generate a warning -# on implicit string concatenation in sequences defined over several lines. -check-str-concat-over-line-jumps=no +# Allow explicit reexports by alias from a package __init__. +allow-reexport-from-package=no +# Allow wildcard imports from modules that define __all__. +allow-wildcard-with-all=no -[SIMILARITIES] +# Deprecated modules which should not be used, separated by a comma. +deprecated-modules= -# Comments are removed from the similarity computation -ignore-comments=yes +# Output a graph (.gv or any supported image format) of external dependencies +# to the given file (report RP0402 must not be disabled). +ext-import-graph= -# Docstrings are removed from the similarity computation -ignore-docstrings=yes +# Output a graph (.gv or any supported image format) of all (i.e. internal and +# external) dependencies to the given file (report RP0402 must not be +# disabled). +import-graph= -# Imports are removed from the similarity computation -ignore-imports=no +# Output a graph (.gv or any supported image format) of internal dependencies +# to the given file (report RP0402 must not be disabled). +int-import-graph= -# Signatures are removed from the similarity computation -ignore-signatures=no +# Force import order to recognize a module as part of the standard +# compatibility libraries. +known-standard-library= -# Minimum lines number of a similarity. -min-similarity-lines=4 +# Force import order to recognize a module as part of a third party library. +known-third-party=enchant + +# Couples of modules and preferred modules, separated by a comma. +preferred-modules= [LOGGING] @@ -415,37 +394,116 @@ logging-format-style=old logging-modules=logging -[VARIABLES] +[MESSAGES CONTROL] -# List of additional names supposed to be defined in builtins. Remember that -# you should avoid defining new builtins when possible. -additional-builtins= +# Only show warnings with the listed confidence levels. Leave empty to show +# all. Valid levels: HIGH, CONTROL_FLOW, INFERENCE, INFERENCE_FAILURE, +# UNDEFINED. +confidence=HIGH, + CONTROL_FLOW, + INFERENCE, + INFERENCE_FAILURE, + UNDEFINED -# Tells whether unused global variables should be treated as a violation. -allow-global-unused-variables=yes +# Disable the message, report, category or checker with the given id(s). You +# can either give multiple identifiers separated by comma (,) or put this +# option multiple times (only on the command line, not in the configuration +# file where it should appear only once). You can also use "--disable=all" to +# disable everything first and then re-enable specific checks. For example, if +# you want to run only the similarities checker, you can use "--disable=all +# --enable=similarities". If you want to run only the classes checker, but have +# no Warning level messages displayed, use "--disable=all --enable=classes +# --disable=W". +disable=raw-checker-failed, + bad-inline-option, + locally-disabled, + file-ignored, + suppressed-message, + useless-suppression, + deprecated-pragma, + use-symbolic-message-instead, + missing-module-docstring, + missing-class-docstring, + missing-function-docstring -# List of names allowed to shadow builtins -allowed-redefined-builtins= +# Enable the message, report, category or checker with the given id(s). You can +# either give multiple identifier separated by comma (,) or put this option +# multiple time (only on the command line, not in the configuration file where +# it should appear only once). See also the "--disable" option for examples. +enable=c-extension-no-member -# List of strings which can identify a callback function by name. A callback -# name must start or end with one of those strings. -callbacks=cb_, - _cb -# A regular expression matching the name of dummy variables (i.e. expected to -# not be used). -dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ +[METHOD_ARGS] -# Argument names that match this expression will be ignored. Default to name -# with leading underscore. -ignored-argument-names=_.*|^ignored_|^unused_ +# List of qualified names (i.e., library.method) which require a timeout +# parameter e.g. 'requests.api.get,requests.api.post' +timeout-methods=requests.api.delete,requests.api.get,requests.api.head,requests.api.options,requests.api.patch,requests.api.post,requests.api.put,requests.api.request -# Tells whether we should check for unused import in __init__ files. -init-import=no -# List of qualified module names which can have objects that can redefine -# builtins. -redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io +[MISCELLANEOUS] + +# List of note tags to take in consideration, separated by a comma. +notes=FIXME, + XXX, + TODO + +# Regular expression of note tags to take in consideration. +notes-rgx= + + +[REFACTORING] + +# Maximum number of nested blocks for function / method body +max-nested-blocks=5 + +# Complete name of functions that never returns. When checking for +# inconsistent-return-statements if a never returning function is called then +# it will be considered as an explicit return statement and no message will be +# printed. +never-returning-functions=sys.exit,argparse.parse_error + + +[REPORTS] + +# Python expression which should return a score less than or equal to 10. You +# have access to the variables 'fatal', 'error', 'warning', 'refactor', +# 'convention', and 'info' which contain the number of messages in each +# category, as well as 'statement' which is the total number of statements +# analyzed. This score is used by the global evaluation report (RP0004). +evaluation=max(0, 0 if fatal else 10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)) + +# Template used to display messages. This is a python new-style format string +# used to format the message information. See doc for all details. +msg-template= + +# Set the output format. Available formats are text, parseable, colorized, json +# and msvs (visual studio). You can also give a reporter class, e.g. +# mypackage.mymodule.MyReporterClass. +#output-format= + +# Tells whether to display a full report or only the messages. +reports=no + +# Activate the evaluation score. +score=yes + + +[SIMILARITIES] + +# Comments are removed from the similarity computation +ignore-comments=yes + +# Docstrings are removed from the similarity computation +ignore-docstrings=yes + +# Imports are removed from the similarity computation +ignore-imports=no + +# Signatures are removed from the similarity computation +ignore-signatures=no + +# Minimum lines number of a similarity. +min-similarity-lines=4 [SPELLING] @@ -458,7 +516,7 @@ max-spelling-suggestions=4 spelling-dict= # List of comma separated words that should be considered directives if they -# appear and the beginning of a comment and should not be checked. +# appear at the beginning of a comment and should not be checked. spelling-ignore-comment-directives=fmt: on,fmt: off,noqa:,noqa,nosec,isort:skip,mypy: # List of comma separated words that should not be checked. @@ -472,117 +530,98 @@ spelling-private-dict-file= spelling-store-unknown-words=no -[IMPORTS] - -# List of modules that can be imported at any level, not just the top level -# one. -allow-any-import-level= - -# Allow wildcard imports from modules that define __all__. -allow-wildcard-with-all=no - -# Analyse import fallback blocks. This can be used to support both Python 2 and -# 3 compatible code, which means that the block might have code that exists -# only in one or another interpreter, leading to false positives when analysed. -analyse-fallback-blocks=no - -# Deprecated modules which should not be used, separated by a comma. -deprecated-modules= - -# Output a graph (.gv or any supported image format) of external dependencies -# to the given file (report RP0402 must not be disabled). -ext-import-graph= - -# Output a graph (.gv or any supported image format) of all (i.e. internal and -# external) dependencies to the given file (report RP0402 must not be -# disabled). -import-graph= - -# Output a graph (.gv or any supported image format) of internal dependencies -# to the given file (report RP0402 must not be disabled). -int-import-graph= - -# Force import order to recognize a module as part of the standard -# compatibility libraries. -known-standard-library= - -# Force import order to recognize a module as part of a third party library. -known-third-party=enchant +[STRING] -# Couples of modules and preferred modules, separated by a comma. -preferred-modules= +# This flag controls whether inconsistent-quotes generates a warning when the +# character used as a quote delimiter is used inconsistently within a module. +check-quote-consistency=no +# This flag controls whether the implicit-str-concat should generate a warning +# on implicit string concatenation in sequences defined over several lines. +check-str-concat-over-line-jumps=no -[CLASSES] -# Warn about protected attribute access inside special methods -check-protected-access-in-special-methods=no +[TYPECHECK] -# List of method names used to declare (i.e. assign) instance attributes. -defining-attr-methods=__init__, - __new__, - setUp, - __post_init__ +# List of decorators that produce context managers, such as +# contextlib.contextmanager. Add to this list to register other decorators that +# produce valid context managers. +contextmanager-decorators=contextlib.contextmanager -# List of member names, which should be excluded from the protected access -# warning. -exclude-protected=_asdict, - _fields, - _replace, - _source, - _make +# List of members which are set dynamically and missed by pylint inference +# system, and so shouldn't trigger E1101 when accessed. Python regular +# expressions are accepted. +generated-members= -# List of valid names for the first argument in a class method. -valid-classmethod-first-arg=cls +# Tells whether to warn about missing members when the owner of the attribute +# is inferred to be None. +ignore-none=yes -# List of valid names for the first argument in a metaclass class method. -valid-metaclass-classmethod-first-arg=cls +# This flag controls whether pylint should warn about no-member and similar +# checks whenever an opaque object is returned when inferring. The inference +# can return multiple potential results while evaluating a Python object, but +# some branches might not be evaluated, which results in partial inference. In +# that case, it might be useful to still emit no-member and other checks for +# the rest of the inferred objects. +ignore-on-opaque-inference=yes +# List of symbolic message names to ignore for Mixin members. +ignored-checks-for-mixins=no-member, + not-async-context-manager, + not-context-manager, + attribute-defined-outside-init -[DESIGN] +# List of class names for which member attributes should not be checked (useful +# for classes with dynamically set attributes). This supports the use of +# qualified names. +ignored-classes=optparse.Values,thread._local,_thread._local -# List of regular expressions of class ancestor names to ignore when counting -# public methods (see R0903) -exclude-too-few-public-methods= +# Show a hint with possible names when a member name was not found. The aspect +# of finding the hint is based on edit distance. +missing-member-hint=yes -# List of qualified class names to ignore when counting class parents (see -# R0901) -ignored-parents= +# The minimum edit distance a name should have in order to be considered a +# similar match for a missing member name. +missing-member-hint-distance=1 -# Maximum number of arguments for function / method. -max-args=10 +# The total number of similar names that should be taken in consideration when +# showing a hint for a missing member. +missing-member-max-choices=1 -# Maximum number of attributes for a class (see R0902). -max-attributes=10 +# Regex pattern to define which classes are considered mixins. +mixin-class-rgx=.*[Mm]ixin -# Maximum number of boolean expressions in an if statement (see R0916). -max-bool-expr=5 +# List of decorators that change the signature of a decorated function. +signature-mutators= -# Maximum number of branch for function / method body. -max-branches=12 -# Maximum number of locals for function / method body. -max-locals=30 +[VARIABLES] -# Maximum number of parents for a class (see R0901). -max-parents=7 +# List of additional names supposed to be defined in builtins. Remember that +# you should avoid defining new builtins when possible. +additional-builtins= -# Maximum number of public methods for a class (see R0904). -max-public-methods=25 +# Tells whether unused global variables should be treated as a violation. +allow-global-unused-variables=yes -# Maximum number of return / yield for function / method body. -max-returns=20 +# List of names allowed to shadow builtins +allowed-redefined-builtins= -# Maximum number of statements in function / method body. -max-statements=50 +# List of strings which can identify a callback function by name. A callback +# name must start or end with one of those strings. +callbacks=cb_, + _cb -# Minimum number of public methods for a class (see R0903). -min-public-methods=2 +# A regular expression matching the name of dummy variables (i.e. expected to +# not be used). +dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ +# Argument names that match this expression will be ignored. +ignored-argument-names=_.*|^ignored_|^unused_ -[EXCEPTIONS] +# Tells whether we should check for unused import in __init__ files. +init-import=no -# Exceptions that will emit a warning when being caught. Defaults to -# "BaseException, Exception". -overgeneral-exceptions=BaseException, - Exception +# List of qualified module names which can have objects that can redefine +# builtins. +redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io diff --git a/requirements_dev.txt b/requirements_dev.txt index 016d22d..0ec7dc9 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -1,6 +1,6 @@ -astroid==2.13.3 +astroid==2.14.1 attrs==22.2.0 -black==22.12.0 +black==23.1.0 click==8.1.3 dill==0.3.6 exceptiongroup==1.1.0 @@ -18,7 +18,7 @@ platformdirs==2.6.2 pluggy==1.0.0 prettytable==3.6.0 psycopg2==2.9.5 -pylint==2.15.10 +pylint==2.16.1 pytest==7.2.1 texttable==1.6.7 tomli==2.0.1 diff --git a/src/pg_lock_tracer/animate_lock_graph.py b/src/pg_lock_tracer/animate_lock_graph.py index 295d2b0..cc1036e 100755 --- a/src/pg_lock_tracer/animate_lock_graph.py +++ b/src/pg_lock_tracer/animate_lock_graph.py @@ -391,10 +391,10 @@ def main(): args = parser.parse_args() if not os.path.exists(args.input_file): - raise Exception(f"Input file does not exist {args.input_file}") + raise ValueError(f"Input file does not exist {args.input_file}") if os.path.exists(args.output_file) and not args.force: - raise Exception(f"Output file already exists {args.output_file}") + raise ValueError(f"Output file already exists {args.output_file}") # Create a new dot model, process the events in the input file # and generate the HTML output diff --git a/src/pg_lock_tracer/helper.py b/src/pg_lock_tracer/helper.py index ee6ec00..e0c91d7 100644 --- a/src/pg_lock_tracer/helper.py +++ b/src/pg_lock_tracer/helper.py @@ -76,7 +76,7 @@ def lock_type_to_str(lock_type): if lock_numeric_value == lock_type: return lock_name - raise Exception(f"Unsupported lock type {lock_type}") + raise ValueError(f"Unsupported lock type {lock_type}") @staticmethod def lock_type_to_int(lock_name): @@ -85,7 +85,7 @@ def lock_type_to_int(lock_name): """ if lock_name not in PostgreSQLLockHelper.locks: - raise Exception(f"Unknown lock type {lock_name}") + raise ValueError(f"Unknown lock type {lock_name}") return PostgreSQLLockHelper.locks[lock_name] @@ -111,7 +111,7 @@ def read_bpf_program(program_name): program_file = Path(__file__).parent / "bpf" / program_name if not os.path.exists(program_file): - raise Exception(f"BPF program file not found {program_file}") + raise ValueError(f"BPF program file not found {program_file}") with program_file.open("r") as bpf_program: return bpf_program.read() diff --git a/src/pg_lock_tracer/oid_resolver.py b/src/pg_lock_tracer/oid_resolver.py index 0893db3..afe7dac 100644 --- a/src/pg_lock_tracer/oid_resolver.py +++ b/src/pg_lock_tracer/oid_resolver.py @@ -97,7 +97,6 @@ def fetch_oid_from_db(self, oid): oid = str(oid) try: - self.cur.execute( select_stmt, [ diff --git a/src/pg_lock_tracer/pg_lock_tracer.py b/src/pg_lock_tracer/pg_lock_tracer.py index b1e3b56..5752517 100755 --- a/src/pg_lock_tracer/pg_lock_tracer.py +++ b/src/pg_lock_tracer/pg_lock_tracer.py @@ -193,7 +193,6 @@ class PGError(IntEnum): class LockStatisticsEntry: def __init__(self) -> None: - # The number of requested locks self._lock_count = 0 @@ -264,7 +263,6 @@ def update_statistics(self, event, oid_value): Add the lock call to the statistics and measure lock request time """ if event.event_type == Events.LOCK_RELATION_OID: - if oid_value not in self.statistics: self.statistics[oid_value] = LockStatisticsEntry() @@ -347,7 +345,6 @@ def handle_output_line(self, line): class PGLockTraceOutputHuman(PGLockTraceOutput): - # pylint: disable=too-many-branches, too-many-statements def print_event(self, _cpu, data, _size): """ @@ -447,7 +444,7 @@ def print_event(self, _cpu, data, _size): elif event.event_type == Events.DEADLOCK: output = f"{print_prefix} DEADLOCK DETECTED" else: - raise Exception(f"Unsupported event type {event.event_type}") + raise ValueError(f"Unsupported event type {event.event_type}") self.handle_output_line(output) self.print_stacktace_if_available(event) @@ -574,9 +571,8 @@ def __init__(self, prog_args): self.oid_resolvers = {} for oid_resolver_url in self.args.oid_resolver_urls: - if ":" not in oid_resolver_url: - raise Exception( + raise ValueError( f"Resolver URL has to be in format: 'PID:URL' ({oid_resolver_url} was provided)" ) @@ -598,22 +594,21 @@ def __init__(self, prog_args): # Belong the processes to the binary? for pid in self.args.pids: - if not os.path.isdir(f"/proc/{pid}"): - raise Exception( + raise ValueError( f"/proc entry for pid {pid} not found, does the process exist?" ) binary = os.readlink(f"/proc/{pid}/exe") if binary != self.args.path: - raise Exception( + raise ValueError( f"Pid {pid} does not belong to binary {self.args.path}. Executable is {binary}" ) # Does the output file already exists? if self.args.output_file and os.path.exists(self.args.output_file): - raise Exception(f"Output file {self.args.output_file} already exists") + raise ValueError(f"Output file {self.args.output_file} already exists") @staticmethod def generate_c_defines(stacktrace_events, verbose): @@ -677,7 +672,9 @@ def init(self): # pylint: disable=consider-using-with self.output_file = open(self.args.output_file, "w", encoding="utf-8") if not self.output_file.writable(): - raise Exception(f"Output file {self.args.output_file} is not writeable") + raise ValueError( + f"Output file {self.args.output_file} is not writeable" + ) # Output as human readable text or as json? self.output_class = ( @@ -708,7 +705,7 @@ def register_probe(self, function_regex, bpf_fn_name, probe_on_enter=True): ) if not func_and_addr: - raise Exception(f"Unable to locate function {function_regex}") + raise ValueError(f"Unable to locate function {function_regex}") # Handle address duplicates for function, address in func_and_addr: diff --git a/src/pg_lock_tracer/pg_lw_lock_tracer.py b/src/pg_lock_tracer/pg_lw_lock_tracer.py index 315df77..867f55b 100755 --- a/src/pg_lock_tracer/pg_lw_lock_tracer.py +++ b/src/pg_lock_tracer/pg_lw_lock_tracer.py @@ -78,7 +78,6 @@ class Events(IntEnum): class LockStatisticsEntry: def __init__(self) -> None: - # The number of non-waited requested locks self._direct_lock_count = 0 @@ -254,7 +253,7 @@ def resolve_lock_mode(event): if event.mode == 2: # LW_WAIT_UNTIL_FREE return "LW_WAIT_UNTIL_FREE" - raise Exception(f"Unknown event type {event.event_type}") + raise ValueError(f"Unknown event type {event.event_type}") def print_lock_event(self, _cpu, data, _size): """ @@ -304,7 +303,7 @@ def print_lock_event(self, _cpu, data, _size): "/ LWLockConditionalAcquire()" ) else: - raise Exception(f"Unknown event type {event.event_type}") + raise ValueError(f"Unknown event type {event.event_type}") def init(self): """