-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Rewrite of parse_alphanumeric_range and expand_alphanumeric_pattern #13728
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
Rewrite of parse_alphanumeric_range and expand_alphanumeric_pattern #13728
Conversation
Range "568" is invalid when creating interface with names vlan [568,570]
For some reason, the current test suite expects expand_alphanumeric_pattern('r[9-a]a') to return an empty list and not thow an exception like it does in all other error cases? That makes no sense.
…d expand_alphanumeric_pattern
Oh, one more thing, if anyone's tempted to clean up ALPHANUMERIC_EXPANSION_PATTERN to be a little more precise in what patterns it matches... well... you could, but then you'd break about half the unit tests, because of how the unit tests expect some wonky stuff to be passed through and some to have exceptions thrown. It was out of scope so I left it alone. |
…nd_alphanumeric_pattern, and simplify implementation
I slept on it and came up on the idea of extracting the "warty" behaviour into its own function, and also ended up with a cleaner recursive implementation that's a lot easier to read than the itertools.product monstrosity I wrote yesterday. I also decided that expand_alphanumeric_pattern throwing forms.ValidationError was bogus and made it throw ValueError, and have the caller do that translation itself. This change in interface ended up requiring (justified) changes to the unit tests to expect a different exception type. However, after this cleanup, I've discovered something else lurking under the surface that I think I'd need some clarity on, so I'm going to leave this PR non-ready for now until I can get a gauge on the correct behaviour. I'll come back and clarify what I mean by that, I'll extract that out as a seperate bug report. |
Actually, on second thought, I think the right context to put it is within this PR. Anyway, the problem I've found (that was pre-existing before I even started working on this) is that the unit tests are testing compeltely dead code. Let me explain.
netbox/netbox/utilities/forms/fields/expandable.py Lines 32 to 33 in a8a36c0
As I have discovered in this refactoring, that means that, if there's nothing that looks like a range expression in the code, it'll just end up using the interface name with no changes. However, that also means that some unit tests are flawed, such as these ones and others: netbox/netbox/utilities/tests/test_forms.py Lines 275 to 286 in a8a36c0
If we for example look at the test case of In effect, these tests (and others like it) end up testing dead code paths, and do not test the actual code path taken when the user puts in a value. Now, in my opinion, the correct way to handle this is to remove the test in Either we modify the tests to reflect the fact that a test case like Or, we consider that the case of entering something In my opinion, neither behaviour is inherently more correct or wrong, so I think it makes sense for NetBox from an external standpoint to keep doing what it's always done, and to update the tests to test its actual behaviour instead of testing the dead code. So that's why I'm going ahead and changing these unit tests to reflect actual reality, even though the behaviour hasn't changed. But there's a lot going on here, so I'm going to take a step back here and go back to the develop branch and re-factor the calling code and the unit tests seperately, and then merge them in here once I'm convinced the unit tests are valid both before and after. |
Actually, I'm just going ahead to make a new PR, this one is just way too verbose and difficult for anyone other than myself to follow. I'll make a seperate PR that's more organized and easier to review. Sorry for any confusion so far. |
Fixes: #13722
The code for
expand_alphanumeric_pattern
andparse_alphanumeric_range
which is used to expand range expressions such asGi1/0/[1-24]
had got a bit unruly and at least one bug had snuck in where a case likevlan[123,456]
could not be parsed correctly. (Issue #13722).The goal here was to add a unit test for that broken behaviour and then fix it. Fixing it turned into a complete rewrite/refactor of these two functions, because they had reached a point where they were no longer maintainable as is.
This refactor surfaced two other unexpected behaviours:
When passing a pattern like
r[a-9]a
, which is invalid because it makes no sense to try to make a range from a letter to a number, the existing code returned an empty list. Surprisingly, the unit tests also seem to expect this very strange behaviour. Since the behaviour makes no sense, I didn't see any harm in changing the unit tests in order to reflect the new behaviour which is to throw an exception in thie case.There are some warts as to how exception handling works. The old code ended up throwing exceptions implicitly when failing to do number conversion, etc. Instead, I have opted to do explicit checking and exception thowing in all cases I've thought of. However, this surfaced another wart. It seems that depending on the exact nature of the error, sometimes the unit tests expect a
forms.ValidationError
and sometimes aValueError
. In my opinion the correct exception type isValueError
, the functions are generic utility functions and should not be coupled to django forms in any way. However, in an effort to remain bug-for-bug compatible with existing unit tests, I have added some code toexpand_alphanumeric_pattern
to catch and rethrow the exceptions using the "correct" exception type, thereby containing the wart to one place in the code. Fixing it would have to involve changing the unit tests and auditing all calling code, and that didn't really seem to be in the scope of this issue so I've left it be. Instead I've just added some comments for any future housekeeping.Anyway, original bug seems to be squashed, so... mission accomplished?