Skip to content

Conversation

@Gui-FernandesBR
Copy link
Member

Pull request type

Please check the type of change your PR introduces:

  • [ x] Other (please describe): dependency management

Pull request checklist

Please check if your PR fulfills the following requirements, depending on the type of PR:

  • Code base additions (for bug fixes / features):

    • Tests for the changes have been added
    • Lint (black rocketpy) has passed locally and any fixes were made
    • All tests (pytest --runslow) have passed locally

What is the current behavior?

You cannot run "import rocketpy" without getting an error

What is the new behavior?

Inspired in pandas management of optional dependency, I introduced a short function inside tools.py that will deal with the lazy imports of Environment Analysis class. I hope you all like it!

Please notice that all the optional decencies related to Environment Analysis are actually not crucial to run the class.

Plus: I created the requirements-optional.txt to avoid confusions.

Does this introduce a breaking change?

  • No

Other information

@Gui-FernandesBR Gui-FernandesBR added the Bug Something isn't working label Sep 6, 2023
@Gui-FernandesBR Gui-FernandesBR added this to the Release v1.0.0 milestone Sep 6, 2023
@Gui-FernandesBR Gui-FernandesBR self-assigned this Sep 6, 2023
@Gui-FernandesBR
Copy link
Member Author

This bug was reported in our discord server!

Copy link
Collaborator

@phmbressan phmbressan left a comment

Choose a reason for hiding this comment

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

Really good implementation. Concise, organized and easily replicable/scalable.

Still a partial review only since I will test it further later, but things are awesome so far.

Gui-FernandesBR and others added 3 commits September 6, 2023 13:30
Update rocketpy/tools.py

Co-authored-by: Pedro Henrique Marinho Bressan <87212571+phmbressan@users.noreply.github.com>
@Gui-FernandesBR
Copy link
Member Author

@phmbressan I was wondering if there's any easy way to test the import rocketpy import after building the package with pip install without using the [all] option.

Basically the bug passed through our git actions because we always set it to download the package with [all] option.

Idk if this is a matter of solving it with better github actions commands or new creating unit test with pytest. But I think it may be important for us in the future

@MateusStano
Copy link
Member

@phmbressan I was wondering if there's any easy way to test the import rocketpy import after building the package with pip install without using the [all] option.

You can use in Colab:

!pip install git+https://github.com/RocketPy-Team/RocketPy.git@fix/env-analysis-dependency-imports#egg=rocketpy[env_analysis]

I tested it here and it seems some warnings are raised when even when the packages are installed:

image

@Gui-FernandesBR
Copy link
Member Author

@phmbressan I was wondering if there's any easy way to test the import rocketpy import after building the package with pip install without using the [all] option.

You can use in Colab:

!pip install git+https://github.com/RocketPy-Team/RocketPy.git@fix/env-analysis-dependency-imports#egg=rocketpy[env_analysis]

I tested it here and it seems some warnings are raised when even when the packages are installed:

image

Nice catch @MateusStano !

I solved the issue within the last commit. The code was trying to import "windrose>=1.6.8" instead of "windrose", of course it should not work properly.

I think it is running correctly now.

- no longer assigns the issue to its author (only for PRs)
- deleted the useless auto-assign-projects file
- runs the pytest without the [all] option
@Gui-FernandesBR
Copy link
Member Author

@MateusStano , @phmbressan ,

This PR is ready for a re-review now.
I've to added IPython as an optional requirement for the environment analysis class.
Running the class always through jupyter gave me the false idea that IPython was built-in python module.

I hope the code will be working on your machines as well.

Comment on lines 244 to 254
operators = [">=", "<=", "==", ">", "<"]
for requirement in env_analysis_require:
try:
module = import_optional_dependency(requirement)
except ImportError:
pckg_name = requirement
for op in operators:
pckg_name = pckg_name.split(op)[0]
is_present = importlib.util.find_spec(pckg_name)
if is_present is None:
print(
f"{requirement:20} is not installed. Some methods may not work."
f"{pckg_name:20} is not installed. Some methods may not work."
+ " You can install it by running 'pip install rocketpy[env_analysis]'"
)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Some questions:

  1. Have you considered, instead of performing many loops to split the package name, using the split function of the package re native to Python? For example:
import re
pckg_name = re.split("[<>=!]{1,2}", pckg_name)[0]
  1. Your operator list lacks the !=. You could add this to the list or use suggestion I made above which eliminates the need for the operators list.
  2. This seems to be a piece of code that might be needed in the future in many instances, I believe that it would be better to encapsulate this behavior into its own separate function in tools. For instance:
import re

def check_extra_requirements(requirements):
    for requirement in requirements:
        pkg_name = re.split("[<>=!]{1,2}", requirement)[0]
        if importlib.util.find_spec(pkg_name) is None:
            ... # print error

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for solid review.

  1. I didn't know that. See in the last commit how i implemented your suggestion
  2. gotcha!
  3. Alright, I created a new ``tools.check_requirement_version()` function, let's see if you like it. Still prefer to keep other function in the env analysis class so we can do dedicated exception management

Comment on lines 237 to 243
env_analysis_require = [
"timezonefinder",
"windrose>=1.6.8",
"IPython>=8.8.0",
"ipywidgets>=7.6.3",
"jsonpickle",
]
Copy link
Collaborator

Choose a reason for hiding this comment

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

If the package name is splitted and only the first part of the name matters for checking if it is present, why put the version numbers in this list?

I might have overlooked something, but it seems to me that

        env_analysis_require = [
            "timezonefinder",
            "windrose",
            "IPython",
            "ipywidgets",
            "jsonpickle",
        ]

would have the same effect for this function without the need of the versioning. Perhaps it would be useful to keep the versioning and also check if the installed version is compliant, it is likely that the importlib has ways to check that.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes I had left the numbers bc I thought in the future it would be nice to have version numbering tests.
I just "hadn't realized by my own" that this future were so close, so I implemented version checks in my last commit.
This feature can be used in other classes in the future.

Hope you like it now!

@MateusStano
Copy link
Member

Still getting a warning when running on Colab:

image

I think maybe we should lower the IPython version required

@Gui-FernandesBR
Copy link
Member Author

Still getting a warning when running on Colab:

image

I think maybe we should lower the IPython version required

Hey @MateusStano , thks for noticing that. I was wondering if there's any automatic test that we could implement to check if the simulation is running in colab environment. If weren't by you, I would never know the code isn't working there.

Anyway, I have simply dropped the version requirement of ipython. I believe there's no reason for us to demand specific version of this package.

Ready for a re-review then.

@Gui-FernandesBR
Copy link
Member Author

Ready for re-review @phmbressan

@Gui-FernandesBR
Copy link
Member Author

I just improved the version comparison of python packages. It seems that using eval() may not work in 100% of the cases, besides being a security risk.

https://stackoverflow.com/questions/11887762/how-do-i-compare-version-numbers-in-python

@phmbressan
Copy link
Collaborator

phmbressan commented Sep 15, 2023

While testing the latest changes, I ran into this import error:

Python 3.11.5 (main, Sep  7 2023, 19:25:29) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import importlib
>>> importlib.metadata
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'importlib' has no attribute 'metadata'
>>> 

It seems weird that the metadata is not in the standard __init__ of importlib. The GitHub tests also were passing, so to make sure the error was not due to a corrupted venv I tested with a new venv and got the same error. I fixed it with my newest commit, now it seems to be working.

Copy link
Collaborator

@phmbressan phmbressan left a comment

Choose a reason for hiding this comment

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

As I mentioned I my partial review, I really enjoyed this approach to organize optional dependencies imports. Well done!

The main change this PR introduces while adding new packages is to ensure the package is also added to the optional dependency dictionary of the corresponding class exactly as it is in the setup.py.

Perhaps, in the future, it may be interesting to verify these dependencies automatically with importlib.metadata.requires('rocketpy').

@Gui-FernandesBR
Copy link
Member Author

Thank you all for solid reviewing this PR.

I hereby confirm that the code is running locally an in Goggle Collab.

Let's move forward.

@Gui-FernandesBR Gui-FernandesBR merged commit c0e0b1a into beta/v1.0.0 Sep 15, 2023
@Gui-FernandesBR Gui-FernandesBR deleted the fix/env-analysis-dependency-imports branch September 16, 2023 02:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants