-
Notifications
You must be signed in to change notification settings - Fork 161
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
Split attribute quoting from ID quoting, rewrite attribute formatting, store names unquoted #363
Conversation
9ace32a
to
bee1cac
Compare
This pull request has conflicts, please resolve those so that the changes can be evaluated. |
All conflicts have been resolved, thanks! |
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.
Great change, thanks.
I believe that the massive test suite with all the dot files should cover these changes safely?
The tests probably do cover all of this, but I'd feel better adding some extra tests specifically for the rewritten functionality. I started writing some, then stumbled on the fact that it isn't always easy to compare values in the test suite. (On the plus side, trying to compare Node values was how I stumbled on the broken parenting behavior that led to #365.) |
Instead of quote_if_necessary() trying to be all things to all situations, split into quote_id_if_necessary(), which uses the same logic as before, and quote_attr_if_necessary(), which is heavily biased towards quoting, not doing so only if the value is numeric, HTML, or already double-quoted.
Add a _format_attr() function to format single attributes, and call it in a list comprehension when generating formatted attributes for each of the to_string() methods.
`quote_id_if_necessary()` will quote any ID that matches a keyword, except ones it's passed in its `unquoted_keywords` argument. (This is used by `Node.to_string()` to prevent quoting of the `node`, `edge`, and `graph` defaults keywords.)
By storing names without added quotes, using methods like `get_node()` becomes easier, because the string the user has to search for is the same one they initially created the node with. Storing quotes-needed IDs _internally_ unquoted is fine, as long as we always quote them before they're output in `to_string()`.
- Add isalnum() escape-hatch to any_needs_quotes() (instant False) - Add prefix= argument to attrs_string(), to output with a prefix iff a formatted string is produced. (Used to prepend a space when necessary.)
- `test_id_storage_and_lookup` verifies that identifiers are stored in the form they were supplied by the caller (w/r/t quoting of values), can be looked up using the `get_*()` functions in the same format, and are reliably quoted only on output. - `test_keyword_quoting` checks that Dot keywords can be used in graph name fields, node name fields, and attribute fields, and will be quoted to ensure they're parsed correctly. It also verifies that an edge attributes default node will _not_ have its name quoted.
OK, I have just now added sufficient new tests targeted specifically at the functionality in this PR, that I think I can declare it working and verified. (I also fixed the items brought up in review.) I hit on a method of testing that the If, for example, g = pydot.Graph()
a = pydot.Node("my node")
g.add_node(a)
a_out = g.get_node("my node")[0]
self.assertEqual(id(a_out.obj_dict), id(a.obj_dict)) I may even define |
If I'm not mistaken all I've done there is a poor-man's reimplementation of g = pydot.Graph()
a = pydot.Node("my node")
g.add_node(a)
a_out = g.get_node("my node")[0]
self.assertIs(a_out.obj_dict, a.obj_dict) |
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.
Great PR, thank you!
I'll check and close all these issues (where applicable) this weekend.
Amazing work! |
@ferdnyc Well, I shouldn't close the issues until the fixes are properly released. |
Oh... Oops. Sorry, they already closed. The PR was set to auto-close all of them.
I mean, I guess there are two schools of thought on that. As soon as the fix is in the repo, the issue is solved. Anyone who wants to run with the pip install git+https://github.com/pydot/pydot.git (Hmmm... we should probably add that to the README.) |
(Ugh, that reminds me. As much of a pain in the ass as it can be, it's probably a mitzvah if we take the time to rename the |
Oh, that's fine. The release will be coming soon anyway. I'll add that note to README.md and I'll change the branch name. Edit: i see you're the README update. 😄 But I'll do the branch rename |
…as been fixed on pydot/pydot#363 Signed-off-by: Christian López Barrón <chris.gfz@gmail.com>
* removed _check_colon_quotes coming from issue pydot/pydot#258 which has been fixed on pydot/pydot#363 --------- Signed-off-by: Christian López Barrón <chris.gfz@gmail.com>
* removed _check_colon_quotes coming from issue pydot/pydot#258 which has been fixed on pydot/pydot#363 --------- Signed-off-by: Christian López Barrón <chris.gfz@gmail.com>
As the scope of #339 has creeped rather a lot and threatened to push it into a state of perpetual limbo, I've started splitting out some of the changes into more focused PRs. This is another one of those, though the rather far-ranging nature might make it seem otherwise. This PR affects:
Attribute formatting
Common
methods, which all classes'to_string()
methods now call to get their formatted attributessorted()
on attributes into_string()
methods #361 (sorry! I did cherry-pick your test fixes into this PR, though.)Name storage & formatting
.get_*()
methods less confusing/annoying.Closes #361
Closes #355
Closes #181
Fixes #358
Fixes #282
Fixes #258
Fixes #246
Fixes #180
Fixes #111
Fixes #85