krader1961: This is derived from PR #335. That PR prematurely expanded the scope to all vars with a leading underscore. This variant limits it to just the magic `_` var. It is a shame that @smontanaro couldn't set aside their belief that all vars with a leading underscore should be exempt from this check so that they would get credit for the improvement that resolves issue #202.
smontanaro: Note that I added a comment about the docstring in the new test function.
jayvdb: While not strictly relevant to your patch, it would be useful to add a test here to ensure that `_` import is not ignored.

```
    def test_unusedImport_underscore(self):
        self.flakes('import fu as _', m.UnusedImport)
```

With all the `_` special cases happening, I worry that one will become ignored also.
krader1961: I had forgotten I even opened this it's so old. I also see my unit test comment is bogus because I copied it from the flawed PR #334.

```
Don't warn when an unused variable starts with an underscore.
```

That should say something like "Don't warn when the unused variable is the magic underscore var."

@jayvdb Do you want to just merge this and fix the issues yourself or wait for me to muster the energy to address you comment and my observation about the added unit test?
jayvdb: Oh, I missed that :)

It needs to be rebased and docstring fixed before merging.
We can do that for you, if necessary.
diff --git a/pyflakes/checker.py b/pyflakes/checker.py
index bd5eba5..648a224 100644
--- a/pyflakes/checker.py
+++ b/pyflakes/checker.py
@@ -425,7 +425,9 @@ class FunctionScope(Scope):
         Return a generator for the assignments which have not been used.
         """
         for name, binding in self.items():
-            if (not binding.used and name not in self.globals
+            if (not binding.used
+                    and name != '_'  # see issue #202
+                    and name not in self.globals
                     and not self.usesLocals
                     and isinstance(binding, Assignment)):
                 yield name, binding

Ignore "_" vars in "Unused Variable" check

*Original report by [archardlias](https://launchpad.net/~archardlias) on [Launchpad](https://bugs.launchpad.net/bugs/1328169):*

------------------------------------

Would it be possible to ignore variables named "_" from "Unused Variable" checks?

I'm not really sure whether "_" is officially specified anywhere. But I do see it a lot and in a lot of languages including python to denote a variable to be ignored (place holder dummy). PyLint implements this pseudo(?)-convention (? second-hand knowledge).

Would be great, since I would love to be explicit about "things returned but not used" instead of just calling without assignment which looks tantamount to "this function does never return anything / does not contain a return statement". A great plus in signature visibility throughout the code, specially for first-time readers.

Best regards,
~arlias

diff --git a/pyflakes/test/test_imports.py b/pyflakes/test/test_imports.py
index 586a0a5..86e1d37 100644
--- a/pyflakes/test/test_imports.py
+++ b/pyflakes/test/test_imports.py
@@ -94,6 +94,13 @@ class TestImportationObject(TestCase):
         assert binding.source_statement == 'from __future__ import print_function'
         assert str(binding) == '__future__.print_function'
 
+    def test_unusedImport_underscore(self):
+        """
+        The magic underscore var should be reported as unused when used as an
+        import alias.
+        """
+        self.flakes('import fu as _', m.UnusedImport)
+
 
 class Test(TestCase):
 
diff --git a/pyflakes/test/test_other.py b/pyflakes/test/test_other.py
index 364b375..4dbaf23 100644
--- a/pyflakes/test/test_other.py
+++ b/pyflakes/test/test_other.py
@@ -1175,6 +1175,16 @@ class TestUnusedAssignment(TestCase):
             b = 1
         ''', m.UnusedVariable)
 
+    def test_unusedUnderscoreVariable(self):
+        """
+        Don't warn when the magic "_" (underscore) variable is unused.
+        See issue #202.
+        """
+        self.flakes('''
+        def a(unused_param):
+            _ = unused_param
+        ''')
+
     def test_unusedVariableAsLocals(self):
         """
         Using locals() it is perfectly valid to have unused variables

pip install -e .
parse_log_pytest
pytest
flake8 pep8 pytest
3.7
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs @ file:///croot/attrs_1668696182826/work
certifi @ file:///croot/certifi_1671487769961/work/certifi
flake8==5.0.4
flit_core @ file:///opt/conda/conda-bld/flit-core_1644941570762/work/source/flit_core
importlib-metadata==4.2.0
iniconfig @ file:///home/linux1/recipes/ci/iniconfig_1610983019677/work
mccabe==0.7.0
packaging @ file:///croot/packaging_1671697413597/work
pep8==1.7.1
pluggy @ file:///tmp/build/80754af9/pluggy_1648042572264/work
py @ file:///opt/conda/conda-bld/py_1644396412707/work
pycodestyle==2.9.1
-e git+https://github.com/PyCQA/pyflakes.git@4b2d720d86a9ece3115929bef90fb19b29bf160b#egg=pyflakes
pytest==7.1.2
tomli @ file:///opt/conda/conda-bld/tomli_1657175507142/work
typing_extensions @ file:///croot/typing_extensions_1669924550328/work
zipp @ file:///croot/zipp_1672387121353/work

name: pyflakes
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - attrs=22.1.0=py37h06a4308_0
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2022.12.7=py37h06a4308_0
  - flit-core=3.6.0=pyhd3eb1b0_0
  - importlib_metadata=4.11.3=hd3eb1b0_0
  - iniconfig=1.1.1=pyhd3eb1b0_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - packaging=22.0=py37h06a4308_0
  - pip=22.3.1=py37h06a4308_0
  - pluggy=1.0.0=py37h06a4308_1
  - py=1.11.0=pyhd3eb1b0_0
  - pytest=7.1.2=py37h06a4308_0
  - python=3.7.16=h7a1cb2a_0
  - readline=8.2=h5eee18b_0
  - setuptools=65.6.3=py37h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tomli=2.0.1=py37h06a4308_0
  - typing_extensions=4.4.0=py37h06a4308_0
  - wheel=0.38.4=py37h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zipp=3.11.0=py37h06a4308_0
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - flake8==5.0.4
      - importlib-metadata==4.2.0
      - mccabe==0.7.0
      - pep8==1.7.1
      - pycodestyle==2.9.1
prefix: /opt/conda/envs/pyflakes

pyflakes/test/test_other.py::TestUnusedAssignment::test_unusedUnderscoreVariable
pyflakes/test/test_imports.py::TestImportationObject::test_import_as pyflakes/test/test_imports.py::TestImportationObject::test_import_basic pyflakes/test/test_imports.py::TestImportationObject::test_import_submodule pyflakes/test/test_imports.py::TestImportationObject::test_import_submodule_as pyflakes/test/test_imports.py::TestImportationObject::test_import_submodule_as_source_name pyflakes/test/test_imports.py::TestImportationObject::test_importfrom_future pyflakes/test/test_imports.py::TestImportationObject::test_importfrom_member pyflakes/test/test_imports.py::TestImportationObject::test_importfrom_member_as pyflakes/test/test_imports.py::TestImportationObject::test_importfrom_relative pyflakes/test/test_imports.py::TestImportationObject::test_importfrom_relative_parent pyflakes/test/test_imports.py::TestImportationObject::test_importfrom_relative_with_module pyflakes/test/test_imports.py::TestImportationObject::test_importfrom_relative_with_module_as pyflakes/test/test_imports.py::TestImportationObject::test_importfrom_star pyflakes/test/test_imports.py::TestImportationObject::test_importfrom_star_relative pyflakes/test/test_imports.py::TestImportationObject::test_importfrom_submodule_member pyflakes/test/test_imports.py::TestImportationObject::test_importfrom_submodule_member_as pyflakes/test/test_imports.py::TestImportationObject::test_unusedImport_underscore pyflakes/test/test_imports.py::Test::test_aliasedImport pyflakes/test/test_imports.py::Test::test_aliasedImportShadowModule pyflakes/test/test_imports.py::Test::test_assignRHSFirst pyflakes/test/test_imports.py::Test::test_assignedToGlobal pyflakes/test/test_imports.py::Test::test_differentSubmoduleImport pyflakes/test/test_imports.py::Test::test_duplicateSubmoduleImport pyflakes/test/test_imports.py::Test::test_functionNamesAreBoundNow pyflakes/test/test_imports.py::Test::test_functionsRunLater pyflakes/test/test_imports.py::Test::test_futureImport pyflakes/test/test_imports.py::Test::test_futureImportFirst pyflakes/test/test_imports.py::Test::test_futureImportStar pyflakes/test/test_imports.py::Test::test_futureImportUndefined pyflakes/test/test_imports.py::Test::test_futureImportUsed pyflakes/test/test_imports.py::Test::test_ignoreNonImportRedefinitions pyflakes/test/test_imports.py::Test::test_importInClass pyflakes/test/test_imports.py::Test::test_importStar pyflakes/test/test_imports.py::Test::test_importStar_relative pyflakes/test/test_imports.py::Test::test_importUsedInMethodDefinition pyflakes/test/test_imports.py::Test::test_importedInClass pyflakes/test/test_imports.py::Test::test_localImportStar pyflakes/test/test_imports.py::Test::test_methodsDontUseClassScope pyflakes/test/test_imports.py::Test::test_nestedClassAndFunctionScope pyflakes/test/test_imports.py::Test::test_nestedFunctionsNestScope pyflakes/test/test_imports.py::Test::test_newAssignment pyflakes/test/test_imports.py::Test::test_nonGlobalDoesNotRedefine pyflakes/test/test_imports.py::Test::test_notUsedInNestedScope pyflakes/test/test_imports.py::Test::test_packageImport pyflakes/test/test_imports.py::Test::test_redefinedButUsedLater pyflakes/test/test_imports.py::Test::test_redefinedByClass pyflakes/test/test_imports.py::Test::test_redefinedByExcept pyflakes/test/test_imports.py::Test::test_redefinedByFor pyflakes/test/test_imports.py::Test::test_redefinedByFunction pyflakes/test/test_imports.py::Test::test_redefinedBySubclass pyflakes/test/test_imports.py::Test::test_redefinedIf pyflakes/test/test_imports.py::Test::test_redefinedIfElse pyflakes/test/test_imports.py::Test::test_redefinedInClass pyflakes/test/test_imports.py::Test::test_redefinedInNestedFunction pyflakes/test/test_imports.py::Test::test_redefinedInNestedFunctionTwice pyflakes/test/test_imports.py::Test::test_redefinedTry pyflakes/test/test_imports.py::Test::test_redefinedTryElse pyflakes/test/test_imports.py::Test::test_redefinedTryExcept pyflakes/test/test_imports.py::Test::test_redefinedTryExceptElse pyflakes/test/test_imports.py::Test::test_redefinedTryExceptElseFinally pyflakes/test/test_imports.py::Test::test_redefinedTryExceptFinally pyflakes/test/test_imports.py::Test::test_redefinedTryExceptMulti pyflakes/test/test_imports.py::Test::test_redefinedTryNested pyflakes/test/test_imports.py::Test::test_redefinedWhileUnused pyflakes/test/test_imports.py::Test::test_shadowedByFor pyflakes/test/test_imports.py::Test::test_shadowedByForDeep pyflakes/test/test_imports.py::Test::test_shadowedByLambda pyflakes/test/test_imports.py::Test::test_shadowedByParameter pyflakes/test/test_imports.py::Test::test_tryingMultipleImports pyflakes/test/test_imports.py::Test::test_unusedImport pyflakes/test/test_imports.py::Test::test_unusedImport_relative pyflakes/test/test_imports.py::Test::test_unusedInNestedScope pyflakes/test/test_imports.py::Test::test_unusedPackageImport pyflakes/test/test_imports.py::Test::test_unused_package_with_submodule_import pyflakes/test/test_imports.py::Test::test_usedAndGlobal pyflakes/test/test_imports.py::Test::test_usedImport pyflakes/test/test_imports.py::Test::test_usedImport_relative pyflakes/test/test_imports.py::Test::test_usedInAssert pyflakes/test/test_imports.py::Test::test_usedInAssignment pyflakes/test/test_imports.py::Test::test_usedInAttributeAssign pyflakes/test/test_imports.py::Test::test_usedInCall pyflakes/test/test_imports.py::Test::test_usedInClass pyflakes/test/test_imports.py::Test::test_usedInClassBase pyflakes/test/test_imports.py::Test::test_usedInDict pyflakes/test/test_imports.py::Test::test_usedInElifConditional pyflakes/test/test_imports.py::Test::test_usedInElse pyflakes/test/test_imports.py::Test::test_usedInExcept pyflakes/test/test_imports.py::Test::test_usedInExec pyflakes/test/test_imports.py::Test::test_usedInFor pyflakes/test/test_imports.py::Test::test_usedInForElse pyflakes/test/test_imports.py::Test::test_usedInFunction pyflakes/test/test_imports.py::Test::test_usedInGetattr pyflakes/test/test_imports.py::Test::test_usedInGlobal pyflakes/test/test_imports.py::Test::test_usedInIfBody pyflakes/test/test_imports.py::Test::test_usedInIfConditional pyflakes/test/test_imports.py::Test::test_usedInKeywordArg pyflakes/test/test_imports.py::Test::test_usedInLambda pyflakes/test/test_imports.py::Test::test_usedInList pyflakes/test/test_imports.py::Test::test_usedInListComp pyflakes/test/test_imports.py::Test::test_usedInLogic pyflakes/test/test_imports.py::Test::test_usedInOperators pyflakes/test/test_imports.py::Test::test_usedInParameterDefault pyflakes/test/test_imports.py::Test::test_usedInRaise pyflakes/test/test_imports.py::Test::test_usedInReturn pyflakes/test/test_imports.py::Test::test_usedInSlice pyflakes/test/test_imports.py::Test::test_usedInSliceObj pyflakes/test/test_imports.py::Test::test_usedInSubscript pyflakes/test/test_imports.py::Test::test_usedInTry pyflakes/test/test_imports.py::Test::test_usedInTryFinally pyflakes/test/test_imports.py::Test::test_usedInTuple pyflakes/test/test_imports.py::Test::test_usedInWhile pyflakes/test/test_imports.py::Test::test_usedInYield pyflakes/test/test_imports.py::Test::test_used_package_with_submodule_import pyflakes/test/test_imports.py::TestSpecialAll::test_augmentedAssignment pyflakes/test/test_imports.py::TestSpecialAll::test_ignoredInClass pyflakes/test/test_imports.py::TestSpecialAll::test_ignoredInFunction pyflakes/test/test_imports.py::TestSpecialAll::test_importStarExported pyflakes/test/test_imports.py::TestSpecialAll::test_importStarNotExported pyflakes/test/test_imports.py::TestSpecialAll::test_redefinedByGenExp pyflakes/test/test_imports.py::TestSpecialAll::test_unboundExported pyflakes/test/test_imports.py::TestSpecialAll::test_unrecognizable pyflakes/test/test_imports.py::TestSpecialAll::test_usedAsClassDecorator pyflakes/test/test_imports.py::TestSpecialAll::test_usedAsDecorator pyflakes/test/test_imports.py::TestSpecialAll::test_usedInGenExp pyflakes/test/test_imports.py::TestSpecialAll::test_warningSuppressed pyflakes/test/test_other.py::Test::test_attrAugmentedAssignment pyflakes/test/test_other.py::Test::test_breakInsideLoop pyflakes/test/test_other.py::Test::test_breakOutsideLoop pyflakes/test/test_other.py::Test::test_classFunctionDecorator pyflakes/test/test_other.py::Test::test_classNameDefinedPreviously pyflakes/test/test_other.py::Test::test_classNameUndefinedInClassBody pyflakes/test/test_other.py::Test::test_classRedefinedAsFunction pyflakes/test/test_other.py::Test::test_classRedefinition pyflakes/test/test_other.py::Test::test_classWithReturn pyflakes/test/test_other.py::Test::test_classWithYield pyflakes/test/test_other.py::Test::test_classWithYieldFrom pyflakes/test/test_other.py::Test::test_comparison pyflakes/test/test_other.py::Test::test_containment pyflakes/test/test_other.py::Test::test_continueInFinally pyflakes/test/test_other.py::Test::test_continueInsideLoop pyflakes/test/test_other.py::Test::test_continueOutsideLoop pyflakes/test/test_other.py::Test::test_defaultExceptLast pyflakes/test/test_other.py::Test::test_defaultExceptNotLast pyflakes/test/test_other.py::Test::test_doubleAssignmentConditionally pyflakes/test/test_other.py::Test::test_doubleAssignmentWithUse pyflakes/test/test_other.py::Test::test_duplicateArgs pyflakes/test/test_other.py::Test::test_ellipsis pyflakes/test/test_other.py::Test::test_extendedSlice pyflakes/test/test_other.py::Test::test_functionDecorator pyflakes/test/test_other.py::Test::test_functionRedefinedAsClass pyflakes/test/test_other.py::Test::test_globalDeclaredInDifferentScope pyflakes/test/test_other.py::Test::test_identity pyflakes/test/test_other.py::Test::test_localReferencedBeforeAssignment pyflakes/test/test_other.py::Test::test_loopControl pyflakes/test/test_other.py::Test::test_modernProperty pyflakes/test/test_other.py::Test::test_moduleWithReturn pyflakes/test/test_other.py::Test::test_moduleWithYield pyflakes/test/test_other.py::Test::test_moduleWithYieldFrom pyflakes/test/test_other.py::Test::test_redefinedClassFunction pyflakes/test/test_other.py::Test::test_redefinedFunction pyflakes/test/test_other.py::Test::test_redefinedIfElseFunction pyflakes/test/test_other.py::Test::test_redefinedIfElseInListComp pyflakes/test/test_other.py::Test::test_redefinedIfFunction pyflakes/test/test_other.py::Test::test_redefinedInDictComprehension pyflakes/test/test_other.py::Test::test_redefinedInGenerator pyflakes/test/test_other.py::Test::test_redefinedInSetComprehension pyflakes/test/test_other.py::Test::test_redefinedTryExceptFunction pyflakes/test/test_other.py::Test::test_redefinedTryFunction pyflakes/test/test_other.py::Test::test_redefinedUnderscoreFunction pyflakes/test/test_other.py::Test::test_redefinedUnderscoreImportation pyflakes/test/test_other.py::Test::test_starredAssignmentErrors pyflakes/test/test_other.py::Test::test_starredAssignmentNoError pyflakes/test/test_other.py::Test::test_unaryPlus pyflakes/test/test_other.py::Test::test_undefinedBaseClass pyflakes/test/test_other.py::Test::test_varAugmentedAssignment pyflakes/test/test_other.py::TestUnusedAssignment::test_assert_static pyflakes/test/test_other.py::TestUnusedAssignment::test_assert_tuple pyflakes/test/test_other.py::TestUnusedAssignment::test_assert_tuple_empty pyflakes/test/test_other.py::TestUnusedAssignment::test_assert_with_message pyflakes/test/test_other.py::TestUnusedAssignment::test_assert_without_message pyflakes/test/test_other.py::TestUnusedAssignment::test_assignInForLoop pyflakes/test/test_other.py::TestUnusedAssignment::test_assignInListComprehension pyflakes/test/test_other.py::TestUnusedAssignment::test_assignToGlobal pyflakes/test/test_other.py::TestUnusedAssignment::test_assignToMember pyflakes/test/test_other.py::TestUnusedAssignment::test_assignToNonlocal pyflakes/test/test_other.py::TestUnusedAssignment::test_assignmentInsideLoop pyflakes/test/test_other.py::TestUnusedAssignment::test_augmentedAssignmentImportedFunctionCall pyflakes/test/test_other.py::TestUnusedAssignment::test_closedOver pyflakes/test/test_other.py::TestUnusedAssignment::test_dictComprehension pyflakes/test/test_other.py::TestUnusedAssignment::test_doubleClosedOver pyflakes/test/test_other.py::TestUnusedAssignment::test_exceptWithoutNameInFunction pyflakes/test/test_other.py::TestUnusedAssignment::test_exceptWithoutNameInFunctionTuple pyflakes/test/test_other.py::TestUnusedAssignment::test_exceptionUnusedInExcept pyflakes/test/test_other.py::TestUnusedAssignment::test_exceptionUnusedInExceptInFunction pyflakes/test/test_other.py::TestUnusedAssignment::test_exceptionUsedInExcept pyflakes/test/test_other.py::TestUnusedAssignment::test_f_string pyflakes/test/test_other.py::TestUnusedAssignment::test_generatorExpression pyflakes/test/test_other.py::TestUnusedAssignment::test_ifexp pyflakes/test/test_other.py::TestUnusedAssignment::test_listUnpacking pyflakes/test/test_other.py::TestUnusedAssignment::test_setComprehensionAndLiteral pyflakes/test/test_other.py::TestUnusedAssignment::test_tracebackhideSpecialVariable pyflakes/test/test_other.py::TestUnusedAssignment::test_tupleUnpacking pyflakes/test/test_other.py::TestUnusedAssignment::test_unusedVariable pyflakes/test/test_other.py::TestUnusedAssignment::test_unusedVariableAsLocals pyflakes/test/test_other.py::TestUnusedAssignment::test_unusedVariableNoLocals pyflakes/test/test_other.py::TestUnusedAssignment::test_variableUsedInLoop pyflakes/test/test_other.py::TestUnusedAssignment::test_withStatementAttributeName pyflakes/test/test_other.py::TestUnusedAssignment::test_withStatementComplicatedTarget pyflakes/test/test_other.py::TestUnusedAssignment::test_withStatementListNames pyflakes/test/test_other.py::TestUnusedAssignment::test_withStatementNameDefinedInBody pyflakes/test/test_other.py::TestUnusedAssignment::test_withStatementNoNames pyflakes/test/test_other.py::TestUnusedAssignment::test_withStatementSingleName pyflakes/test/test_other.py::TestUnusedAssignment::test_withStatementSingleNameRedefined pyflakes/test/test_other.py::TestUnusedAssignment::test_withStatementSingleNameUndefined pyflakes/test/test_other.py::TestUnusedAssignment::test_withStatementSubscript pyflakes/test/test_other.py::TestUnusedAssignment::test_withStatementSubscriptUndefined pyflakes/test/test_other.py::TestUnusedAssignment::test_withStatementTupleNames pyflakes/test/test_other.py::TestUnusedAssignment::test_withStatementTupleNamesRedefined pyflakes/test/test_other.py::TestUnusedAssignment::test_withStatementTupleNamesUndefined pyflakes/test/test_other.py::TestUnusedAssignment::test_withStatementUndefinedInExpression pyflakes/test/test_other.py::TestUnusedAssignment::test_withStatementUndefinedInside pyflakes/test/test_other.py::TestUnusedAssignment::test_yieldFromUndefined pyflakes/test/test_other.py::TestAsyncStatements::test_asyncDef pyflakes/test/test_other.py::TestAsyncStatements::test_asyncDefAwait pyflakes/test/test_other.py::TestAsyncStatements::test_asyncDefUndefined pyflakes/test/test_other.py::TestAsyncStatements::test_asyncFor pyflakes/test/test_other.py::TestAsyncStatements::test_asyncWith pyflakes/test/test_other.py::TestAsyncStatements::test_asyncWithItem pyflakes/test/test_other.py::TestAsyncStatements::test_continueInAsyncForFinally pyflakes/test/test_other.py::TestAsyncStatements::test_formatstring pyflakes/test/test_other.py::TestAsyncStatements::test_loopControlInAsyncFor pyflakes/test/test_other.py::TestAsyncStatements::test_loopControlInAsyncForElse pyflakes/test/test_other.py::TestAsyncStatements::test_matmul pyflakes/test/test_other.py::TestAsyncStatements::test_raise_notimplemented pyflakes/test/test_other.py::TestAsyncStatements::test_variable_annotations
pyflakes/checker.py
pyflakes/checker.py