Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Python: Minor documantation updates to several quality queries#20052

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Open
joefarebrother wants to merge4 commits intogithub:main
base:main
Choose a base branch
Loading
fromjoefarebrother:python-qual-minor-doc-updates

Conversation

joefarebrother
Copy link
Contributor

Updates documentation of several quality queries, to use python 3 rather than python 2 documentation as references, and a few minor grammatical fixes.

@CopilotCopilotAI review requested due to automatic review settingsJuly 15, 2025 12:31
@joefarebrotherjoefarebrother added the no-change-note-requiredThis PR does not need a change note labelJul 15, 2025
@joefarebrotherjoefarebrother requested a review froma team as acode ownerJuly 15, 2025 12:32
Copy link
Contributor

@CopilotCopilotAI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Pull Request Overview

This PR updates documentation for several Python quality queries to reference Python 3 instead of Python 2 documentation links, along with minor grammatical improvements and formatting fixes.

  • Updates documentation links from Python 2.7 to Python 3 across multiple query help files
  • Fixes grammatical issues by adding missing commas and improving sentence structure
  • Updates code formatting to use backticks for consistency and modernizes Python 2 syntax to Python 3

Reviewed Changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.

Show a summary per file
FileDescription
ConsistentReturns.expectedUpdates error message punctuation (comma addition)
ModificationOfParameterWithDefault.qhelpUpdates Python documentation link from version 2 to 3
InitIsGenerator.qhelpUpdates Python documentation link from version 2.7 to 3
ConsistentReturns.qlImproves code formatting and error message punctuation
ConsistentReturns.qhelpAdds missing comma and updates documentation link
UnsupportedFormatCharacter.qhelpClarifies description and updates documentation link
IncorrectComparisonUsingIs.qlUpdates code formatting for consistency
IncorrectComparisonUsingIs.qhelpUpdates Python documentation link
ExplicitCallToDel.qhelpAdds missing comma for grammatical correctness
DuplicateKeyInDictionaryLiteral.qhelpImproves punctuation and updates documentation link
DuplicateKeyInDictionaryLiteral.pyModernizes Python 2 syntax to Python 3 and adds explanatory comment
CallToSuperWrongClass.qhelpAdds missing commas and updates documentation link
EmptyExcept.qhelpAdds missing comma for grammatical correctness
CatchingBaseException.qhelpUpdates multiple Python documentation links from version 2 to 3

@github-actionsGitHub Actions
Copy link
Contributor

github-actionsbot commentedJul 15, 2025
edited
Loading

QHelp previews:

python/ql/src/Exceptions/CatchingBaseException.qhelp

Except block handles 'BaseException'

All exception classes in Python derive fromBaseException.BaseException has three important subclasses,Exception from which all errors and normal exceptions derive,KeyboardInterrupt which is raised when the user interrupts the program from the keyboard andSystemExit which is raised by thesys.exit() function to terminate the program.

SinceKeyboardInterrupt andSystemExit are special they should not be grouped together with otherException classes.

CatchingBaseException, rather than its subclasses may prevent proper handling ofKeyboardInterrupt orSystemExit. It is easy to catchBaseException accidentally as it is caught implicitly by an emptyexcept: statement.

Recommendation

HandleException,KeyboardInterrupt andSystemExit separately. Do not use the plainexcept: form.

Example

In these examples, a functionapplication.main() is called that might raiseSystemExit. In the first two functions,BaseException is caught, but this will discardKeyboardInterrupt. In the third function,call_main_program_fixed onlySystemExit is caught, leavingKeyboardInterrupt to propagate.

In these examplesKeyboardInterrupt is accidentally ignored.

defcall_main_program_implicit_handle_base_exception():try:#application.main calls sys.exit() when done.application.main()exceptExceptionasex:log(ex)except:passdefcall_main_program_explicit_handle_base_exception():try:#application.main calls sys.exit() when done.application.main()exceptExceptionasex:log(ex)exceptBaseException:passdefcall_main_program_fixed():try:#application.main calls sys.exit() when done.application.main()exceptExceptionasex:log(ex)exceptSystemExit:pass

References

python/ql/src/Exceptions/EmptyExcept.qhelp

Empty except

Ignoring exceptions that should be dealt with in some way is almost always a bad idea. The loss of information can lead to hard to debug errors and incomplete log files. It is even possible that ignoring an exception can cause a security vulnerability. An emptyexcept block may be an indication that the programmer intended to handle the exception, but never wrote the code to do so.

Recommendation

Ensure all exceptions are handled correctly.

Example

In this example, the program keeps running with the same privileges if it fails to drop to lower privileges.

# ...try:security_manager.drop_privileges()exceptSecurityError:pass# ...

References

  • Common Weakness Enumeration:CWE-390.
python/ql/src/Expressions/CallToSuperWrongClass.qhelp

First argument to super() is not enclosing class

Thesuper class should be called with the enclosing class as its first argument andself as its second argument.

Passing a different class may work correctly, provided the class passed is a super class of the enclosing class and the enclosing class does not define an__init__ method. However, this may result in incorrect object initialization if the enclosing class is later subclassed using multiple inheritance.

Recommendation

Ensure that the first argument tosuper() is the enclosing class.

Example

In this example, the call tosuper(Vehicle, self) inCar.__init__ is incorrect, as it passesVehicle rather thanCar as the first argument tosuper. As a result,super(SportsCar, self).__init__() in theSportsCar.__init__ method will not call all__init__() methods because the call tosuper(Vehicle, self).__init__() skipsStatusSymbol.__init__().

classVehicle(object):passclassCar(Vehicle):def__init__(self):#This is OK provided that Car is not subclassed.super(Vehicle,self).__init__()self.car_init()classStatusSymbol(object):def__init__(self):super(StatusSymbol,self).__init__()self.show_off()classSportsCar(Car,StatusSymbol):def__init__(self):#This will not call StatusSymbol.__init__()super(SportsCar,self).__init__()self.sports_car_init()#Fix Car by passing Car to super().#SportsCar does not need to be changed.classCar(Car,Vehicle):def__init__(self):super(Car,self).__init__()self.car_init()

References

python/ql/src/Expressions/DuplicateKeyInDictionaryLiteral.qhelp

Duplicate key in dict literal

Dictionary literals are constructed in the order given in the source. This means that if a key is duplicated, the second key-value pair will overwrite the first; as a dictionary can only have one value per key.

Recommendation

Check for typos to ensure that the keys are supposed to be the same. If they are then decide which value is wanted and delete the other one.

Example

The following example will output"c", because the mapping between 2 and"b" is overwritten by the mapping from 2 to"c". The programmer may have meant to map 3 to"c" instead.

dictionary= {1:"a",2:"b",2:"c"}# BAD: The `2` key is duplicated.print(dictionary[2])

References

python/ql/src/Expressions/ExplicitCallToDel.qhelp

__del__ is called explicitly

The__del__ special method is designed to be called by the Python virtual machine when an object is no longer reachable, but before it is destroyed. Calling a__del__ method explicitly may cause an object to enter an unsafe state.

Recommendation

If explicit clean up of an object is required, aclose() method should be called or, better still, wrap the use of the object in awith statement.

Example

In the first example, rather than close the zip file in a conventional manner, the programmer has called__del__. A safer alternative is shown in the second example.

defextract_bad(zippath,dest):zipped=ZipFile(zippath)try:zipped.extractall(dest)finally:zipped.__del__()defextract_good(zippath,dest):zipped=ZipFile(zippath)try:zipped.extractall(dest)finally:zipped.close()

References

python/ql/src/Expressions/IncorrectComparisonUsingIs.qhelp

Comparison using is when operands support__eq__

When you compare two values using theis oris not operator, it is the object identities of the two values that is tested rather than their equality. If the class of either of the values in the comparison redefines equality then theis operator may returnFalse even though the objects compare as equal. Equality is defined by the__eq__ or, in Python2,__cmp__ method. To compare two objects for equality, use the== or!= operator instead.

Recommendation

When you want to compare the value of two literals, use the comparison operator== or!= in place ofis oris not.

If the uniqueness property or performance are important then use an object that does not redefine equality.

Example

In the first line of the following example the programmer tests the value ofvalue againstDEFAULT using theis operator. Unfortunately, this may fail when the function is called with the string"default".

To function correctly, change the expressionvalue is DEFAULT tovalue == DEFAULT. Alternatively, if the uniqueness property is desirable, then change the definition ofDEFAULT to either of the alternatives below.

DEFAULT="default"defget_color(name,fallback):ifnameinCOLORS:returnCOLORS[name]eliffallbackisDEFAULT:returnDEFAULT_COLORelse:returnfallback#This worksprint (get_color("spam","def"+"ault"))#But this does notprint (get_color("spam","default-spam"[:7]))#To fix the above code change to objectDEFAULT=object()#Or if you want better repr() output:classDefault(object):def__repr__(self):return"DEFAULT"DEFAULT=Default()

References

python/ql/src/Expressions/UnsupportedFormatCharacter.qhelp

Unsupported format character

A printf-style format string (i.e. a string that is used as the left hand side of the% operator, such asfmt % arguments) must consist of valid conversion specifiers, such as%s,%d, etc. Otherwise, aValueError will be raised.

Recommendation

Ensure a valid conversion specifier is used.

Example

In the following example,format_as_tuple_incorrect,%t is not a valid conversion specifier.

defformat_as_tuple_incorrect(args):return"%t"%argsdefformat_as_tuple_correct(args):return"%r"% (args,)

References

python/ql/src/Functions/ConsistentReturns.qhelp

Explicit returns mixed with implicit (fall through) returns

When a function contains both explicit returns (return value) and implicit returns (where code falls off the end of a function), this often indicates that a return statement has been forgotten. It is best to return an explicit return value even when returningNone because this makes it easier for other developers to read your code.

Recommendation

Add an explicit return at the end of the function.

Example

In thecheck_state1 function, the developer probably did intend to use an implicit return value ofNone as this equates toFalse. However, the function incheck_state2 is easier to read.

defcheck_state1(state,interactive=True):ifnotstate['good']ornotstate['bad']:if (goodorbadorskiporreset)andinteractive:return# implicitly return Noneifnotstate['good']:raiseutil.Abort(_('cannot bisect (no known good revisions)'))else:raiseutil.Abort(_('cannot bisect (no known bad revisions)'))returnTruedefcheck_state2(state,interactive=True):ifnotstate['good']ornotstate['bad']:if (goodorbadorskiporreset)andinteractive:returnFalse# return an explicit valueifnotstate['good']:raiseutil.Abort(_('cannot bisect (no known good revisions)'))else:raiseutil.Abort(_('cannot bisect (no known bad revisions)'))returnTrue

References

python/ql/src/Functions/InitIsGenerator.qhelp

__init__ method is a generator

The__init__ method of a class is used to initialize new objects, not create them. As such, it should not return any value. By including ayield expression in the method turns it into a generator method. On calling it will return a generator resulting in a runtime error.

Recommendation

The presence of ayield expression in an__init__ method suggests a logical error, so it is not possible to suggest a general fix.

Example

In this example the__init__ method contains a yield expression. This is not logical in the context of an initializer.

classInitIsGenerator(object):def__init__(self,i):yieldi

References

python/ql/src/Functions/ModificationOfParameterWithDefault.qhelp

Modification of parameter with default

The default value of a parameter is computed once when the function is created, not for every invocation. The "pre-computed" value is then used for every subsequent call to the function. Consequently, if you modify the default value for a parameter this "modified" default value is used for the parameter in future calls to the function. This means that the function may not behave as expected in future calls and also makes the function more difficult to understand.

Recommendation

If a parameter has a default value, do not modify the default value. When you use a mutable object as a default value, you should use a placeholder value instead of modifying the default value. This is a particular problem when you work with lists and dictionaries but there are standard methods of avoiding modifying the default parameter (see References).

Example

In the following example, thedefault parameter is set with a default value of an empty list. Other commands in the function then append values to the list. The next time the function is called, the list will contain values, which may not have been intended.

def__init__(self,name,choices=[],default=[],shortDesc=None,longDesc=None,hints=None,allowNone=1):# 'default' parameter assigned a valueself.choices=choicesifchoicesandnotdefault:default.append(choices[0][1])# value of 'default' parameter modifiedArgument.__init__(self,name,default,shortDesc,longDesc,hints,allowNone=allowNone)

The recommended workaround is use a placeholder value. That is, define the function with a default ofdefault=None, check if the parameter isNone and then set the parameter to a list.

References

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

Copilot code reviewCopilotCopilot left review comments

At least 1 approving review is required to merge this pull request.

Assignees
No one assigned
Labels
documentationno-change-note-requiredThis PR does not need a change notePython
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

1 participant
@joefarebrother

[8]ページ先頭

©2009-2025 Movatter.jp