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

Python 3.13 support. Monkey patches doctest in conftest.py, so doctests pass against both numpy 1 and numpy 2 #68

Open
wants to merge 10 commits into
base: develop
Choose a base branch
from

Conversation

JamesParrott
Copy link

@JamesParrott JamesParrott commented Jan 31, 2025

Describe the proposed changes

  • Relaxes the numpy <2 pin in the optional test dependencies (in pyproject.toml).
  • In conftest.py, swap out doctest.OutputChecker for a sub class of it that does not fail when
    floating points (inc "inf") are wrapped by "np.float64(...)"
  • In .github\workflows\main.yml add Python 3.13 to the test matrix.

Additional information

  • Tested in CI and locally.

Checklist before requesting a review

  • [X ] I have performed a self-review of my code
>uvx ruff check conftest.py
All checks passed!
  • [X ] The code conforms to the style used in this package
    No code style tools are being run in CI. I couldn't find any style guidance elsewhere. Nothing is mentioned in CONTRIBUTING.md. But it's a concise change that's loosely PEP8 compliant, and only changes test code.

  • [X ] The code is fully documented and typed (type-checked with Mypy)
    The entire point of the code in conftest.py is to carry out monkey patching. This relies on Python's dynamic typing, and is
    more trouble than it is worth to statically type. It is also just there to run the tests, so needn't be perfect. Therefore
    I have added #type: ignore to the top of it.

FYI Running mypy on the rest of the project shows that it does not pass type checking anyway:

uvx mypy .
...
Found 219 errors in 25 files (checked 30 source files)

I'll gladly help fix those, if further PRs to that end will be accepted. But these 'errors' have nothing to do with this PR.

  • [X ] I have added thorough tests for the new/changed functionality
    Extending the Python versions that the tests are run on (while avoiding spurious failures due to breaking changes in Numpy) is the entire goal of this PR.

@JamesParrott
Copy link
Author

I should add, I found the numpy <2 pin only prevented the test dependencies from being installed on Windows CI runners. The tests still passed anyway, running Numpy 1 on Python 3.13 on the Ubuntu and MacOS runners.

Nonetheless, it's much better to test against the version of Numpy most users will install.
https://github.com/JamesParrott/dcor/actions/runs/13054075998

Copy link
Owner

@vnmabus vnmabus left a comment

Choose a reason for hiding this comment

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

Thank you so much! I think I will accept this as is, for now. However, I wonder if it won't be better to do the opposite, that is, to use the new repr of NumPy 2.0 in the doctests, given that it will be the one users will likely install.

@@ -28,7 +28,7 @@ jobs:
- name: Run tests
run: |
pip3 install ".[test]"
coverage run --source=dcor/ --omit=dcor/tests/ -m pytest
coverage run --source=dcor/ --omit=dcor/tests/ -m pytest --doctest-glob=""
Copy link
Owner

Choose a reason for hiding this comment

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

What is this for?

Copy link
Author

Choose a reason for hiding this comment

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

Ah sorry, that's from a previous experiment. I'll remove it.

@JamesParrott
Copy link
Author

Thanks for the fast response Carlos. You're very welcome.

Re: changing the doc strings to Numpy2.
This is possible of course, but the PR contain a change in nearly every file containing a docstring. And manual checks are needed for any native Python floats that should not be wrapped by numpy.float64(...).
Similarly, the logic could be changed, to wrap the expected, instead of removing the wrapper from the actual (if it is not already wrapped). But the extra checks or work to check for native floats still need to be done in that case.

It's hard to imagine anything inadvertantly having a repr of numpy.float64(...) that isn't one, and that therefore shouldn't be have that removed. But if that's a concern, the doctest could be allowed to pass if it's equal whether or not the wrapper is removed, or if we have equality after the wrapper is removed from both got and wanted.

@vnmabus
Copy link
Owner

vnmabus commented Jan 31, 2025

Re: changing the doc strings to Numpy2. This is possible of course, but the PR contain a change in nearly every file containing a docstring. And manual checks are needed for any native Python floats that should not be wrapped by numpy.float64(...). Similarly, the logic could be changed, to wrap the expected, instead of removing the wrapper from the actual (if it is not already wrapped). But the extra checks or work to check for native floats still need to be done in that case.

I know it is difficult, that is one of the reasons I didn't do it yet (the other is lack of time).

or if we have equality after the wrapper is removed from both got and wanted.

Actually, that would allow the doctests to be gradually moved to NumPy 2, right? Maybe that would be the best choice.

@JamesParrott
Copy link
Author

Re: changing the doc strings to Numpy2. This is possible of course, but the PR contain a change in nearly every file containing a docstring. And manual checks are needed for any native Python floats that should not be wrapped by numpy.float64(...). Similarly, the logic could be changed, to wrap the expected, instead of removing the wrapper from the actual (if it is not already wrapped). But the extra checks or work to check for native floats still need to be done in that case.

I know it is difficult, that is one of the reasons I didn't do it yet (the other is lack of time).

or if we have equality after the wrapper is removed from both got and wanted.

Actually, that would allow the doctests to be gradually moved to NumPy 2, right? Maybe that would be the best choice.

Yes you're right. The doctests could be mixed and matched then (between Numpy 1 and Numpy 2).

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.

2 participants