-
Notifications
You must be signed in to change notification settings - Fork 192
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
Use only one global var for marking config folder tree #6610
Conversation
for more information, see https://pre-commit.ci
0db80ec
to
418cc2a
Compare
e3e89d1
to
d7f3684
Compare
02307b3
to
959a9ad
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #6610 +/- ##
==========================================
+ Coverage 77.51% 77.90% +0.40%
==========================================
Files 560 567 +7
Lines 41444 42178 +734
==========================================
+ Hits 32120 32856 +736
+ Misses 9324 9322 -2 ☔ View full report in Codecov by Sentry. |
344fe89
to
1b26044
Compare
30bae8b
to
c4adbec
Compare
for more information, see https://pre-commit.ci
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If basedpyright
is happy with the code, there is probably nothing I can add :D
Looks good to me! Just a few minor comments.
Co-authored-by: Julian Geiger <julian.geiger@psi.ch>
c9a7c04
to
95e305c
Compare
for more information, see https://pre-commit.ci
KEY_STORAGE, | ||
KEY_PROCESS, | ||
) | ||
|
||
def __init__(self, name: str, config: Mapping[str, Any], validate=True): | ||
def __init__( | ||
self, name: str, config: abc.Mapping[str, Any], config_folder: pathlib.Path | None = None, validate: bool = True |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good to know, but unless we actually use it somewhere I would remove this for now.
614990f
to
6ec11a4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the review and great suggestion @danielhollas @sphuber
I addressed all what you mentioned, and ready for another review I think.
Hi @danielhollas, please have a look at this when you get time. This is one of the fixes for a random failed test of #6620. Besides the naming of the get/set methods, it is ready from my side. I prefer to have the method name |
@unkcpz Thanks, I'll have a look today. One suggestion, it would help if the unrelated typing changes were extracted to a separate PR. But if it would be too much extra work don't worry about it.
I agree with the rename. |
d180e0b
to
aec9321
Compare
Not too many, and I agree it is better to not contaminate the major changes with fix type checking too much. I revert the changes in
Renamed. |
def create_instance_directories() -> None: | ||
@final | ||
class AiiDAConfigDir: | ||
"""Singleton for setting and getting the path to configuration directory.""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"""Singleton for setting and getting the path to configuration directory.""" | |
"""Global access class that hold the attribute for the absolute path of AiiDA configuration folder. The class method ``set`` and ``get`` are provided to mutate and access the location of configuration folder.""" |
Look back and the implementation, I think it is not the actually singleton pattern, which only instantiate the object once and only once for entire program.
The old change I put was having a _glb_aiida_config_folder
variable and it seems fit more with the global variable of the module and the module in python is a singleton so the global variable will therefore shared over the entire program.
In the current implementation, it is AiiDAconfigDir._glb_aiida_config_folder
the class attribute plays this global variable role.
I think the new docstring above makes more sense for the class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is indeed definitely not a singleton. I think I left a comment before asking why you went with a class and a class attribute to store the global config directory, but I cannot find it nor a response. I still don't really see why this requires a class? Wouldn't it be perfectly fine to simply do:
_AIIDA_CONFIG_FOLDER: pathlib.Path | None = None
def get():
global _AIIDA_CONFIG_FOLDER
return _AIIDA_CONFIG_FOLDER
def set(aiida_config_folder):
global _AIIDA_CONFIG_FOLDER
_AIIDA_CONFIG_FOLDER = aiida_config_folder
_create_instance_directories(aiida_config_folder)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I implemented in this way and then agree with @danielhollas it would be better to move as class attribute to the class.
Logically it is the same as current implementation, just the difference of how codes are organized and how the set/get functions are called.
With class and attributes, the class server as the global variable with the module, and get/set are called by:
from aiida.manage.configuration.settings import AiiDAconfigDir
AiiDAconfigDir.set("/tmp/.aiida")
config_folder = AiiDAconfigDir.get()
with global variable of module, get/set are called by:
from aiida.manage.configuation import settings
settings.set_configuration_folder("/tmp/.aiida")
config_folder = settings.get_configuration_folder()
I personally prefer the AiiDAConfigDir
way which seems more compact.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, in the end it is a matter of taste. I just wanted to ask because I don't like this general attitude that "everything must be a class". There are plenty of situations where creating an entire class for a simple function is not necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like this general attitude that "everything must be a class".
Yep, I totally agree with this ;)
I am not yet on the haskell side that "everthing must be a function" but I am definitely fan of classes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is another advantage of using global
keyword which is I have to put the # PLW0608
to silent the mypy. It makes it easier to find where we use the global variables. Usually those are places that may not thread-safe.
@danielhollas want to hear what you think, I think after separate the AiiDAConfigPathResover
out, it seems better to not using AiiDAConifgDir
to encapsulate it as @sphuber suggested?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am in favour of keeping the AiiDAConfigDir
class, I like how it encapsulates the global variable. Otherwise, it's too easy to modify the global variable directly, without going through the setter. (Yes, I am aware that one can modify the class variables directly as well, but not without intentional effort.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great! Thanks for sticking with this @unkcpz, very nice cleanup and the settings.py
file is now much easier to follow.
def create_instance_directories() -> None: | ||
@final | ||
class AiiDAConfigDir: | ||
"""Singleton for setting and getting the path to configuration directory.""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am in favour of keeping the AiiDAConfigDir
class, I like how it encapsulates the global variable. Otherwise, it's too easy to modify the global variable directly, without going through the setter. (Yes, I am aware that one can modify the class variables directly as well, but not without intentional effort.)
Thanks for the review and discussion! @sphuber @danielhollas @GeigerJ2 |
The problem is found when I worked on #6609. If the import of
DAEMON_DIR
moved to outside the function, the global var set in module scope and in test contest will not be reset when function is loading.The goal for a better design is to reduce the use of global variable. Now it is only the
glb_aiida_config_folder
(the originalAIIDA_CONFIG_FOLDER
). Other three are derived from this one. This lower the possibility of directly access the global variable without noticing its change.