-
Notifications
You must be signed in to change notification settings - Fork 24
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
Override mechanism for primitive value merge #76
Conversation
semver comparisons quickly becoming a complicated set operation
Hello @malachib |
setup.py
Outdated
@@ -15,7 +15,8 @@ | |||
installrequires = [ | |||
'PyYAML<7', | |||
'Jinja2>3,<4', | |||
'MarkupSafe<3' | |||
'MarkupSafe<3', | |||
'semantic-version>2' |
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.
As the dependency is not required for the basic functionality, I would like to take this out of the installrequires
.
diff --git a/setup.py b/setup.py
index 6360adb..1701d2c 100755
--- a/setup.py
+++ b/setup.py
@@ -15,8 +15,7 @@ long_description = open('README.rst').read()
installrequires = [
'PyYAML<7',
'Jinja2>3,<4',
- 'MarkupSafe<3',
- 'semantic-version>2'
+ 'MarkupSafe<3'
]
In order to make your test work, I would recommend using a new file
--- /dev/null 2024-08-25 06:33:22.535323361 +0200
+++ test/requirements.txt 2024-08-27 04:52:58.992351951 +0200
@@ -0,0 +1,2 @@
+# test/test_mergeoverride.py
+semantic-version>2
and use this in the coresponding places in the Makefile
diff --git a/Makefile b/Makefile
index 7a9be60..2855e45 100644
--- a/Makefile
+++ b/Makefile
@@ -101,6 +101,7 @@ testinstallvirtualenv:
echo ""; \
echo " ... test install ..."; \
python -c 'import sys; from hiyapyco import __version__ as HIYAPYCOVERSION; print ("hiyapyco %s" % HIYAPYCOVERSION); print (sys.version)'; \
+ pip install -r test/requirements.txt; \
make test; \
make examples; \
deactivate; \
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.
Hello @malachib
As discussed, please remove the semantic-version
dependency and if you like include test/requirements.txt
stuff fromm the diff above
hiyapyco/__init__.py
Outdated
@@ -185,6 +186,12 @@ def __init__(self, *args, **kwargs): | |||
self.encoding = kwargs['encoding'] | |||
del kwargs['encoding'] | |||
|
|||
self.mergeprimitive = lambda a, b, context: b |
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.
In favor of a better readability I would prefer to use here
diff --git a/hiyapyco/__init__.py b/hiyapyco/__init__.py
index d096b31..6296caf 100644
--- a/hiyapyco/__init__.py
+++ b/hiyapyco/__init__.py
@@ -186,7 +186,7 @@ class HiYaPyCo:
self.encoding = kwargs['encoding']
del kwargs['encoding']
- self.mergeprimitive = lambda a, b, context: b
+ self.mergeprimitive = None
if 'mergeoverride' in kwargs:
# DEBT: Compare to make sure function signature is right
self.mergeprimitive = kwargs['mergeoverride']
@@ -427,8 +427,12 @@ class HiYaPyCo:
logger.debug('pass as b is None')
pass
if a is None or isinstance(b, primitiveTypes):
- logger.debug('deepmerge: replace a "%s" w/ b "%s"' % (a, b,))
- a = self.mergeprimitive(a, b, context)
+ if self.mergeprimitive is None:
+ logger.debug('deepmerge: replace a "%s" w/ b "%s"' % (a, b,))
+ a = b
+ else:
+ logger.debug('deepmerge: call mergeprimitive for a "%s", b "%s" with context' % (a, b,))
+ a = self.mergeprimitive(a, b, context)
elif isinstance(a, listTypes):
if isinstance(b, listTypes):
logger.debug(
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.
Hello @malachib
you should create a new commit including the change
- self.mergeprimitive = lambda a, b, context: b
+ self.mergeprimitive = None
or something similar here before resolving it
hiyapyco/__init__.py
Outdated
@@ -416,7 +428,7 @@ def _deepmerge(self, a, b): | |||
pass | |||
if a is None or isinstance(b, primitiveTypes): | |||
logger.debug('deepmerge: replace a "%s" w/ b "%s"' % (a, b,)) | |||
a = b | |||
a = self.mergeprimitive(a, b, context) |
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.
see comment above.
I know it is not that fancy and pythonic
, but it increases readability IMHO
if a is None or isinstance(b, primitiveTypes):
- logger.debug('deepmerge: replace a "%s" w/ b "%s"' % (a, b,))
- a = self.mergeprimitive(a, b, context)
+ if self.mergeprimitive is None:
+ logger.debug('deepmerge: replace a "%s" w/ b "%s"' % (a, b,))
+ a = b
+ else:
+ logger.debug('deepmerge: call mergeprimitive for a "%s", b "%s" with context' % (a, b,))
+ a = self.mergeprimitive(a, b, context)
elif isinstance(a, listTypes):
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.
Hello @malachib
Please include the diff above in a new commit
Thx
@zerwes all of this strikes me as entirely reasonable. I didn't even notice a Makefile was out there, and it didn't even dawn on me that yes incurring that semver dependency on the overall library was a big whoopsie. Good catch. I'd argue leaving Thanks for the props on testing :) At the risk of sounding harsh, writing code without associated unit tests is amateur hour!! no thank you!! Also I am a bit sheepish about the pseudo-semver support in the test, but it turns out merging ranges of semver is pretty hard |
I would consider your enhancement introducing
You can rename if a is None or isinstance(b, primitiveTypes):
- logger.debug('deepmerge: replace a "%s" w/ b "%s"' % (a, b,))
- a = self.mergeprimitive(a, b, context)
+ if self.mergeprimitive is None:
+ logger.debug('deepmerge: replace a "%s" w/ b "%s"' % (a, b,))
+ a = b
+ else:
+ logger.debug('deepmerge: call mergeprimitive for a "%s", b "%s" with context' % (a, b,))
+ a = self.mergeprimitive(a, b, context)
elif isinstance(a, listTypes): I know, it is not that fancy and maybe not that pythonic clean, but sometimes more code is uncool, but much more readable. This way one can understand what happens here even if looking at the code 2 years later without knowledge of this PR.
Full ACK for "no test is no-go". |
Roger that. I respect that logic. In my own code special measures are needed sometimes to ensure that even I remember what the heck I did.
Thank you. I would tease that I snuck some bad code in there, but in 2024 it's too scary to even joke about that! All in all, I am A-OK with your enhancements. |
Yes, that's the point. During the 2to3 migration I had to touch many of my old scripts ... and it gave me several times some head-scratching ...
😞 Sad but true ...
👍 as soon as you have integrated them in your PR I can merge it and send some clacks around announcing a new release |
OK, I naively clicked "resolve conversation". This is my first time adjusting a PR this way. Did I do it right? Canonical instructions left me a little flat |
No problem, we all do things the first time ... and github has sometimes a own and imho sometimes strange logic... Otherwise I would have to merge your PR into a new dev branch and commit the proposed changes by my own and then merge my own dev branch into main... but that is not reflecting the real way changes have comme in, as it is your feature and PR, not mine (i.e. not clean in terms of git history and I do not want to adorn myself with other people's laurels) |
I believe I understand. Your proposed changes, being diffs, I had this idea there was a merge/accept button I could press somewhere to merge each proposed change in. Instead it appears I need to hand-recreate those in my own commits for my PR. I will do that |
yes, would be nice, but there is no such feature to my knowledge (but as I noted, /me is no gh pro) |
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.
👍 for the commit message 😄
Thank you @malachib |
Additional load parameter
mergeoverride
is a function-as-an-argument to customize a or b selection during primitive value type merges (such as ints, strings, etc)I made this since I need something that can choose semver ranges in overlaid yaml build configs.
The "last overlay wins" approach is quite sensible, but once in a while you hit an edge case like this one.