refactor: bind optional lookups once instead of calling get twice - #52
Open
blaipr wants to merge 1 commit into
Open
refactor: bind optional lookups once instead of calling get twice#52blaipr wants to merge 1 commit into
blaipr wants to merge 1 commit into
Conversation
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
Six places call `.get()` twice on the same dictionary, once to test it and once to use it:
```python
if kwargs.get('project'):
payload.update(project=kwargs.get('project').id, playbook=playbook)
```
That is correct. The guard does protect the access, and nothing mutates the dictionary in between. It reads poorly, it does the lookup twice, and a type checker cannot connect the two calls, so each one shows up as "Attribute `id` is not defined on `None`". Binding once fixes all three at no cost:
```python
project = kwargs.get('project')
if project:
payload.update(project=project.id, playbook=playbook)
```
Applied in `job_templates.py`, `projects.py`, `workflow_job_templates.py` twice, and `page.py` twice.
**One in the same family is a real improvement rather than a tidy-up.** `logged_sleep` did this:
```python
try:
frm = inspect.stack()[stack_depth]
logger = logging.getLogger(inspect.getmodule(frm[0]).__name__)
except AttributeError: # module is None (interactive shell)
logger = log
```
The comment is right about why: `inspect.getmodule` returns `None` for a frame with no module, which is what an interactive shell gives. But catching `AttributeError` to detect that also swallows any other `AttributeError` raised inside the `try`, including one from `inspect.stack()` itself. The `None` is now tested for directly, so only the case the comment describes is handled and anything else surfaces.
**Correcting something I said in ctrliq#42 and ctrliq#51.** I described these as latent `AttributeError`s waiting to happen. They are not: every one is guarded. They are a readability and double-lookup issue that a checker happens to notice, and this change is worth making on those grounds, not on a correctness scare.
Seven diagnostics retired, 131 to 124. Diffed the full list before and after: strict subset, nothing introduced.
Verified with `black --check`, `flake8`, the unit suite at 355 passing, and `logged_sleep(0)` exercising the rewritten path.
blaipr
force-pushed
the
refactor/bind-optional-lookups-once
branch
from
September 13, 2026 09:03
b90a563 to
95a4b0b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Six places call
.get()twice on the same dictionary, once to test it and once to use it:That is correct. The guard does protect the access, and nothing mutates the dictionary in between. It reads poorly, it does the lookup twice, and a type checker cannot connect the two calls, so each one shows up as "Attribute
idis not defined onNone". Binding once fixes all three at no cost:Applied in
job_templates.py,projects.py,workflow_job_templates.pytwice, andpage.pytwice.One in the same family is a real improvement rather than a tidy-up.
logged_sleepdid this:The comment is right about why:
inspect.getmodulereturnsNonefor a frame with no module, which is what an interactive shell gives. But catchingAttributeErrorto detect that also swallows any otherAttributeErrorraised inside thetry, including one frominspect.stack()itself. TheNoneis now tested for directly, so only the case the comment describes is handled and anything else surfaces.Correcting something I said in #42 and #51. I described these as latent
AttributeErrors waiting to happen. They are not: every one is guarded. They are a readability and double-lookup issue that a checker happens to notice, and this change is worth making on those grounds, not on a correctness scare.Seven diagnostics retired, 131 to 124. Diffed the full list before and after: strict subset, nothing introduced.
Verified with
black --check,flake8, the unit suite at 355 passing, andlogged_sleep(0)exercising the rewritten path.