Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

py client version check fixes and cleanup #1497

Merged
merged 8 commits into from
Jul 25, 2024
Merged

Conversation

melange396
Copy link
Collaborator

fixes on top of #1456, to address CI failures seen in #1496

@melange396 melange396 requested a review from minhkhul July 19, 2024 14:44
@melange396
Copy link
Collaborator Author

i believe this test is now broken (or is at least inadequate) :

@patch('delphi.epidata.client.delphi_epidata.Epidata._version_check')
def test_version_check_once(self, version_check):
"""Test that the _version_check() function is only called once on initial module import."""
from delphi.epidata.client.delphi_epidata import Epidata
version_check.assert_not_called()

rzats
rzats previously approved these changes Jul 19, 2024
Copy link
Contributor

@rzats rzats left a comment

Choose a reason for hiding this comment

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

Since _version_checked is now tracked as a class variable, it might be worth adding it to the test you've mentioned - this would verify that the state persists across repeated imports but _version_check() is only called once:

  @patch('delphi.epidata.client.delphi_epidata.Epidata._version_check')
  def test_version_check_once(self, version_check):
    """Test that the _version_check() function is only called once on initial module import."""
    from delphi.epidata.client.delphi_epidata import Epidata
    self.assertTrue(Epidata._version_checked)
    version_check.assert_not_called()

@staticmethod
def log(evt, **kwargs):
kwargs['event'] = evt
kwargs['timestamp'] = time.strftime("%Y-%m-%d %H:%M:%S %z")
return sys.stderr.write(str(kwargs) + "\n")

# Check that this client's version matches the most recent available, runs just once per program execution (on initial module load).
# Check that this client's version matches the most recent available.
# This is indended to run just once per program execution, on initial module load.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
# This is indended to run just once per program execution, on initial module load.
# This is intended to run just once per program execution, on initial module load.

Copy link
Contributor

@dshemetov dshemetov left a comment

Choose a reason for hiding this comment

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

I was surprised that this test didn't error:

  @patch('delphi.epidata.client.delphi_epidata.Epidata._version_check')
  def test_version_check_once(self, version_check):
    """Test that the _version_check() function is only called once on initial module import."""
    from delphi.epidata.client.delphi_epidata import Epidata
    version_check.assert_not_called()

Since we moved the flag check inside the function, _version_check() should be called and then take the quick exit branch. But this doesn't error, so _version_check() was never called, which lead me to think that Python doesn't rerun a module once it's imported and this turns out to be true.

The first place checked during import search is sys.modules. This mapping serves as a cache of all modules that have been previously imported, including the intermediate paths. So if foo.bar.baz was previously imported, sys.modules will contain entries for foo, foo.bar, and foo.bar.baz. Each key will have as its value the corresponding module object.

From The module cache.

You can test it like this:

# a.py
class Test:
    @staticmethod
    def hello():
        print("Hello")

class Test2:
    pass

Test.hello()

# b.py
from a import Test
from a import Test2epidatpy git:(dev) ✗ python b.py
Hello

This holds even a is imported in different files.

So it seems like we don't actually need this flag and my bad for suggesting all this unneeded stuff. We probably don't need the unit tests associated with the check running only once either, since we don't need to test Python's import system; just test that _version_check writes the right log message and call it done. Would be good to write a comment explaining that _version_check will automatically only run on the first import.

minhkhul
minhkhul previously approved these changes Jul 19, 2024
Copy link
Contributor

@minhkhul minhkhul left a comment

Choose a reason for hiding this comment

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

Agree w Rostyslav on unit test. Also, just curious, what does e___vdc stands for?
Edit: just read through Dmitry's suggestions.

fix: simplify client version check
@minhkhul minhkhul dismissed stale reviews from rzats and themself via ca5d74d July 24, 2024 18:21
dshemetov
dshemetov previously approved these changes Jul 24, 2024
Copy link

sonarcloud bot commented Jul 25, 2024

@melange396 melange396 requested a review from minhkhul July 25, 2024 14:00
@melange396 melange396 merged commit 72b4050 into dev Jul 25, 2024
7 checks passed
@melange396 melange396 deleted the pyclient_vercheck_fix branch July 25, 2024 18:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants