Skip to main content
added 4 characters in body
Source Link
J_H
  • 43.3k
  • 3
  • 38
  • 158

Prefer e.g. “hello”"hello" over f”hello”f"hello"

Prefer e.g. “hello” over f”hello”

Prefer e.g. "hello" over f"hello"

added 34 characters in body
Source Link
J_H
  • 43.3k
  • 3
  • 38
  • 158

Of course the code at one point had properly defined foo. But then as the months go on thingthings change, and we never retried that print(), so it's embarrassing when it finally triggers. Routine static analysis with ruff, pyright, or mypy on each git push can help to surface such a "whoops!".

No need for an f-string when there's no { } params, such as f"foo = {foo}"

Prefer e.g. “hello” over f”hello”

Of course the code at one point had properly defined foo. But then as the months go on thing change, and we never retried that print(), so it's embarrassing when it finally triggers. Routine static analysis with ruff, pyright, or mypy on each git push can help to surface such a "whoops!".

No need for an f-string when there's no { } params, such as f"foo = {foo}"

Of course the code at one point had properly defined foo. But then as the months go on things change, and we never retried that print(), so it's embarrassing when it finally triggers. Routine static analysis with ruff, pyright, or mypy on each git push can help to surface such a "whoops!".

No need for an f-string when there's no { } params, such as f"foo = {foo}"

Prefer e.g. “hello” over f”hello”

Source Link
J_H
  • 43.3k
  • 3
  • 38
  • 158

version hardcodes

To dry up run_test_old_and_new_code(), it looks like we want a helper that accepts a version number such as "1.0.0" or "2.7.0". In _dynamic_val() the 2.7.0 default is very nice, but it didn't carry over to this function. And 2.7.0 appears in many logging statements and calls. At some point 2.7.1 will be relevant, and we risk having a maintainer replace just a subset of the versions that will need updating.

error handling

Some of these try blocks seem to correspond to "impossible" or "never happens" conditions, which your automated tests do not try to exercise. If so, then consider removing the try, making the error fatal. The default stack trace display will be more informative than what the OP code displays. If there's some specific logging requirement in your specifications document, then deal with it at top level in a uniform way, instead of down within the various helpers.

OOP

There is no __init__() constructor, indeed, no self.foo attributes at all. This suggests that what you really wanted was a collection of functions, rather than methods hanging off an object instance.

It is usual to tack on a @staticmethod decorator on methods which don't rely on self. Here, we might have noticed that all the helpers are static, and the pair of entry points in the Public API only use self for dispatch to a helper.

temp file cleanup

There's no """docstring""" on this helper to explain the concept of operations. Consider having _dynamic_val() return a Path, which caller is expected to .unlink(), perhaps via a with context handler. Currently it appears that such files accumulate without bound.

wrong exit

if not os.path.exists(CONDA_PATH):
    ...
    exit

The two development process difficulties here are:

  1. This doesn't work.
  2. You never ran that line of code.

The first is easy: add import sys and call sys.exit()

The second is tougher, since it corresponds to adopting a brand new habit and exercising it each day that you write code. I have personally written error handlers like this, which error at exactly the time you were hoping they would instead be helpful. Recommend that you introduce a deliberate typographic error ("C:/does/not/exist") when defining that path, and verify it's handled as you desire. Then revert the typo, and don't worry about that clause until the next time you mess with the if test or the body.

A pretty common way to lose in such a handler is with NameError.

# foo = 42
if is_failed():
    print("failed, with foo =", foo)

Of course the code at one point had properly defined foo. But then as the months go on thing change, and we never retried that print(), so it's embarrassing when it finally triggers. Routine static analysis with ruff, pyright, or mypy on each git push can help to surface such a "whoops!".

lint

It is customary to use LOGGER.exception() when reporting on some exception e, in order to reveal the call site via the displayed stack trace.

No need for an f-string when there's no { } params, such as f"foo = {foo}"