Skip to content

Assorted typing cleanups#4842

Merged
bdbaddog merged 1 commit intoSCons:masterfrom
mwichmann:maint/typeniggles
Mar 30, 2026
Merged

Assorted typing cleanups#4842
bdbaddog merged 1 commit intoSCons:masterfrom
mwichmann:maint/typeniggles

Conversation

@mwichmann
Copy link
Copy Markdown
Collaborator

@mwichmann mwichmann commented Mar 25, 2026

Fix various niggly typing and checker complaints.

Environment.py:

  • To avoid modifying a dict-like thing while iterating over it, we did .copy(), making an awkward chained construct that checkers don't like. Simpler (and the more common idiom) is to make a list from the keys view, that way you're iterating over that new list and not the dict (and save creating a dict copy).
  • Another use of copy() was in detecting a CPPDEFINES deque, where we want to keep a copy of it and not modify the original - use the deque constructor for this instead of calling copy() method.
  • A few complaints about calling subst with a bad type were due to us defeating type narrowing - checkers don't know that is_String evaluating true means the object is a string type. Added casts for certain instances of this.
  • Align the names of vars in overridden dunder methods in BuilderDict with parent UserDict for more consistency (one of ours used the same name as a different arg in the parent). Similar for the JSONEncoder default method.
  • arg2nodes node_factory argument could be passed a None, indicate that in the signature.
  • Multiple uses of CacheDir (it was both an import from CacheDir for type checking, and the name of a function in Environment.py). This was confusing to at least one type checker, so just use the qualified name.
  • The environment Base class _update and _update_onlynew methods were annotated to take an EnvironmentBase argument, but in fact they're designed to update the internal dict from a passed dict. Adjusted the annotation.
  • Used the global Environment hook directly by name rather than fully qualified, as SCons.Environment doesn't have an import of itself. That's namespace niggling, because it worked as written.
  • The Repository method (public API level) was written to take kwargs and pass those on to the FS layer's Repository - which doesn't take kwargs. Repository() was never documented as accepting any keyword arguments (and no tests ever poked at that usage), so just removed to align the two.
  • In VariantDir, make a small readability change and also avoid reassigning the function parameters: the index-zero access occurs on the call to self.fs.VariantDir, not on the end of the call to arg2nodes.

Node/FS.py: Glob and glob annotation adjusted to show the exclude argument could also be a single string, as that could be passed down from the public API level, as documented: "The optional exclude argument may be set to a pattern or a list of patterns describing files or directories to filter out of the match list."

Tool/FortranCommon.py: fix an error where returns were annotated Tuple, which is not imported; changed to tuple.

Util/__init__.py: use a typevar for semi_deepcopy, which is a dispatch function, type checkers don't seem to read through to the return types of the various copy functions it calls.

No test changes - for the small code changes, we want to show behavior didn't change.

Contributor Checklist:

  • I have created a new test or updated the unit tests to cover the new/changed functionality.
  • I have updated CHANGES.txt and RELEASE.txt (and read the README.rst).
  • I have updated the appropriate documentation

Fix various niggly typing and checker complaints.

Environment.py:

* To avoid modifying a dict-like thing while iterating over it, we did
  .copy(), making an awkward chained construct that checkers don't like.
  Simpler (and the more common idion) is to make a list out of the .keys()
  view, that way you're iterating over that new list and not the dict
  (and save creating a dict copy).
* A few complaints about calling subst with a bad type were due to us
  defeating type narrowing - checkers don't know that is_String evaluating
  true means the object is a string type. Added casts for some of these.
* Another use of copy() was in detecting a CPPDEFINES deque, where we
  want to keep a copy of it and not modify the original - use the deque
  constructor for this instead of calling copy() method.
* Align the names of vars in overridden dunder methods in BuilderDict with
  parent UserDict for more consistency.
* arg2nodes node_factory argument *could* be passed a None, indicate
  that in the signature.
* Multiple uses of CacheDir (it was both an import from CacheDir for type
  checking, and the name of a function in Environment.py). This was confusing
  to at least one type checker, so just use the qualified name.
* The environment Base class _update and _update_onlynew methods
  were annotated to take an EnvironmentBase argument, but in fact they're
  designed to update the internal dict from a passed dict.  Adjusted the
  annotation.
* Used the global Environment hook directly by name rather than fully
  qualified, as SCons.Environment doesn't have an import of itself.  That's
  namespace niggling, because it worked as written.
* The Repository method (public API level) was written to take kwargs and
  pass those on to the FS layer's Repository - which doesn't take kwargs.
  Repository() was never documented as accepting any keyword arguments
  (and no tests ever poked at that usage), so just removed to align the two.
* In VariantDir, make a small readability change and also avoid
  reassigning the function parameters: the index-zero access occurs on the
  call to self.fs.VariantDir, not on the end of the call to arg2nodes.

Node/FS.py: Glob and glob annotation adjusted to show the exclude argument
could also be a single string, as that could be passed down from the public
API level, as documented: "The optional exclude argument may be set to a
pattern or a list of patterns describing files or directories to filter out of
the match list."

Tool/FortranCommon.py: fix an error where returns were Tuple, which is
not imported; changed to tuple.

Add more typing casts to Environment

A few complaints about calling subst with a bad type were due to
us defeating type narrowing - checkers don't know that is_String
evaluating true means the object is a string type. Added casts
for certain instances of this.

Signed-off-by: Mats Wichmann <mats@linux.com>
Copy link
Copy Markdown
Contributor

@Repiteo Repiteo left a comment

Choose a reason for hiding this comment

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

Everything seems to check out!

Will need RELEASE.txt updated, though

@mwichmann
Copy link
Copy Markdown
Collaborator Author

Everything seems to check out!

Will need RELEASE.txt updated, though

I dodged it as there are already three entries there that collectively say Environment was tweaked for typing and docstrings. I figure it's covered... will wait to hear.

@bdbaddog bdbaddog merged commit 3f89316 into SCons:master Mar 30, 2026
10 of 12 checks passed
@mwichmann mwichmann added this to the NextRelease milestone Mar 30, 2026
@mwichmann mwichmann deleted the maint/typeniggles branch March 30, 2026 13:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants