jendrikseipp / vulture

Find dead Python code
MIT License
3.45k stars 152 forks source link

Confusing recursive processing of directory #357

Closed dmwyatt closed 4 months ago

dmwyatt commented 4 months ago

I have a Django project with this Vulture config:

[tool.vulture]
exclude = [
  "*/settings.py",
  "*/settings/*.py",
  "*/migrations/*.py",
]
ignore_decorators = [
  # Django
  "@receiver",
  "@register.filter",
  "@register.inclusion_tag",
  "@register.simple_tag",
  # django.contrib.admin
  "@admin.action",
  "@admin.display",
  "@admin.register",
  # pytest
  "@pytest.fixture",
]
ignore_names = [
  # Django
  "*Config",  # AppConfig subclasses
  "*Middleware",
  "clean_*",
  "Meta",
  "urlpatterns",
  # django.contrib.admin
  "get_extra",
  "get_fieldsets",
  "has_add_permission",
  "has_change_permission",
  "has_delete_permission",
  "has_view_permission",
  "lookups",
  "sender"
]

sort_by_size = true
min_confidence = 70

If I run vulture . in the project root I get:

> vulture .
conftest.py:27: unused variable 'db' (100% confidence, 1 line)
core\apps.py:10: unused import 'checks' (90% confidence, 1 line)
core\tests\test_views.py:9: unused variable 'db' (100% confidence, 1 line)
core\tests\test_views.py:90: unused variable 'field_name' (100% confidence, 1 line)
registration\tests\test_forms.py:10: unused variable 'db' (100% confidence, 1 line)

If I run it against one of the directories within the project I get a more comprehensive result:

> vulture core
core\apps.py:10: unused import 'checks' (90% confidence, 1 line)
core\apps.py:10: unused import 'signals' (90% confidence, 1 line)
core\checks.py:38: unused variable 'kwargs' (100% confidence, 1 line)
core\checks.py:83: unused variable 'kwargs' (100% confidence, 1 line)
core\checks.py:231: unused variable 'kwargs' (100% confidence, 1 line)
core\management\commands\ngrok.py:58: unused variable 'args' (100% confidence, 1 line)
core\management\commands\show_urls.py:86: unused variable 'args' (100% confidence, 1 line)
core\signals.py:9: unused variable 'kwargs' (100% confidence, 1 line)
core\signals.py:15: unused variable 'kwargs' (100% confidence, 1 line)
core\signals.py:22: unused variable 'kwargs' (100% confidence, 1 line)
core\tests\test_email_utils.py:7: unused variable 'args' (100% confidence, 1 line)
core\tests\test_email_utils.py:7: unused variable 'kwargs' (100% confidence, 1 line)
core\tests\test_models.py:1: unused import 'timedelta' (90% confidence, 1 line)
core\tests\test_views.py:9: unused variable 'db' (100% confidence, 1 line)
core\tests\test_views.py:90: unused variable 'field_name' (100% confidence, 1 line)

My understanding was that vulture would recursively descend against all files, but that's not what I'm seeing here I don't think.

With vulture . it does some descent (see core/tests for example). But it does more when I pass the directory as the path to check...

whosayn commented 4 months ago

what results seem out of place for what invocation? I assume the difference in results is because there are directories outside of core that use the newly reported entries i.e. results from vulture core - vulture ..

dmwyatt commented 4 months ago

Here's an example of something in core.signals:

@receiver(post_save, sender=CustomUser)
def update_is_published_on_user_change(sender, instance, **kwargs):
    EmailSite.objects.update_publish_status(instance)

When I call vulture core it reports that **kwargs as being unused. When I call vulture . it is not unused.

The thing is, is this function is never called by my own code, it's called internally by Django's code. As such, I would have thought it'd be identified as unused with either invocation...and regardless kwargs isn't used within the function.

whosayn commented 4 months ago

Oh, I see. When vulture parses the AST, I don't think there's currently a distinction between calls from thirdparty and internal apis. I could be wrong, but I think that'd explain the discrepancy

jendrikseipp commented 4 months ago

When I call vulture core it reports that **kwargs as being unused. When I call vulture . it is not unused.

Vulture ignores scopes. The vulture . fails to report kwargs as being unused because there's another function that uses kwargs.