Add type annotations to djblets.siteconfig.

Review Request #12702 — Created Oct. 28, 2022 and submitted

Information

Djblets
release-3.x

Reviewers

djblets.siteconfig, and SiteConfiguration in particular, is central
to much of the Djblets and Review Board codebases. This change
inrtoduces type annotations to most of the module, helping to make sure
call sites are passing in all the right information.

Settings management in SiteConfiguration is all typed now, helping
callers ensure they're handling results correctly.

Mappings between siteconfig and Django settings are typed with
structured TypeDicts, so we can avoid any issues with invalid keys or
values in those sometimes-complex mappings.

This was fairly smooth, though it did uncover a couple code paths where
assumptions were incorrectly made. Unbound varibable issues were fixed
in the management commands

All unit tests pass for all supported versions of Python.

Mypy and pyright were largely happy. There's some work in related modules
that still need to be done.

Summary ID
Add type annotations to djblets.siteconfig.
`djblets.siteconfig`, and `SiteConfiguration` in particular, is central to much of the Djblets and Review Board codebases. This change inrtoduces type annotations to most of the module, helping to make sure call sites are passing in all the right information. Settings management in `SiteConfiguration` is all typed now, helping callers ensure they're handling results correctly. Mappings between siteconfig and Django settings are typed with structured `TypeDict`s, so we can avoid any issues with invalid keys or values in those sometimes-complex mappings. This was fairly smooth, though it did uncover a couple code paths where assumptions were incorrectly made. Unbound varibable issues were fixed in the management commands
217011be690b2e2d947d3f2e616f0df16856c7f9
Description From Last Updated

'djblets.siteconfig.models.SiteConfigurationSettings' imported but unused Column: 1 Error code: F401

reviewbotreviewbot

'typing.Any' imported but unused Column: 1 Error code: F401

reviewbotreviewbot

Typo (I think?) "Djangos" -> "Django"

maubinmaubin

Would it be worth it to include the type here like value: SiteConfigurationSettingsValue = siteconfig.get(key)?

maubinmaubin

Typo: "are" -> "that are"

maubinmaubin

Forgot to add str type.

maubinmaubin

Could add unused here.

maubinmaubin

Should add doc comments for these.

maubinmaubin

Forgot to add str type.

maubinmaubin

*args should come after clear_caches. Also will need to add *args to the doc string.

maubinmaubin
Checks run (1 failed, 1 succeeded)
flake8 failed.
JSHint passed.

flake8

chipx86
maubin
  1. 
      
  2. djblets/siteconfig/django_settings.py (Diff revision 2)
     
     
    Show all issues

    Typo (I think?) "Djangos" -> "Django"

    1. All good catches, thanks!

  3. djblets/siteconfig/django_settings.py (Diff revision 2)
     
     
    Show all issues

    Would it be worth it to include the type here like value: SiteConfigurationSettingsValue = siteconfig.get(key)?

    1. That should be inferred through .get().

  4. djblets/siteconfig/forms.py (Diff revision 2)
     
     
    Show all issues

    Typo: "are" -> "that are"

  5. djblets/siteconfig/forms.py (Diff revision 2)
     
     
    Show all issues

    Forgot to add str type.

  6. djblets/siteconfig/forms.py (Diff revision 2)
     
     
    Show all issues

    Could add unused here.

  7. djblets/siteconfig/models.py (Diff revision 2)
     
     
     
     
     
     
     
    Show all issues

    Should add doc comments for these.

  8. djblets/siteconfig/models.py (Diff revision 2)
     
     
    Show all issues

    Forgot to add str type.

  9. djblets/siteconfig/models.py (Diff revision 2)
     
     
     
    Show all issues

    *args should come after clear_caches. Also will need to add *args to the doc string.

    1. This is a weirdness with the new keyword-only argument syntax.

      Python 3 allows arguments to be declared as keyword-only, so they won't be passed as positionals. These are listed after either a *args or a plain *. So these are both valid examples:

      def func1(pos1, pos2, *, kwonly1=True, **kwargs):
          ...
      
      def func2(post1, post2, *args, kwonly1=True, **kwargs):
          ...
      

      I'll fix the docs.

    2. Ah I see. I was only aware of the * way of doing that. Good to know.

    3. Yeah it's not immediately obvious. And in fact, I put it right before **kwargs when I first wrote it, and had to go fix that.

  10. 
      
chipx86
david
  1. Ship It!
  2. 
      
chipx86
Review request changed
Status:
Completed
Change Summary:
Pushed to release-3.x (264627b)