Skip to content
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

Create and test Node and ItemNode #72

Merged
merged 10 commits into from
Nov 1, 2019

Conversation

sydneyli
Copy link
Contributor

@sydneyli sydneyli commented Oct 4, 2019

Fleshing out API as described in #49. Starting with generic Node and a more specific ItemNode implementation.

@sydneyli sydneyli force-pushed the writable-loader-item branch from d0a6722 to 9e8eb4f Compare October 4, 2019 02:21
@codecov-io
Copy link

codecov-io commented Oct 4, 2019

Codecov Report

❗ No coverage uploaded for pull request base (master@27845ec). Click here to learn what that means.
The diff coverage is 46.66%.

Impacted file tree graph

@@            Coverage Diff            @@
##             master      #72   +/-   ##
=========================================
  Coverage          ?   87.64%           
=========================================
  Files             ?        7           
  Lines             ?      688           
  Branches          ?        0           
=========================================
  Hits              ?      603           
  Misses            ?       85           
  Partials          ?        0
Impacted Files Coverage Δ
apacheconfig/__init__.py 100% <100%> (ø)
apacheconfig/wloader.py 43.85% <43.85%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 27845ec...1fa014d. Read the comment docs.

Copy link
Owner

@etingof etingof left a comment

Choose a reason for hiding this comment

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

Great start! I have some nits in-line.

@sydneyli
Copy link
Contributor Author

sydneyli commented Oct 4, 2019

Thanks for the feedback! I addressed some of the comments-- I'll try to address the rest of them with the following:

  • Sphinx-ify the docs
  • Flake8 on test_wloader.py

@sydneyli
Copy link
Contributor Author

sydneyli commented Oct 5, 2019

Documentation/testing sprint done! While doing that I also changed the constructor a bit-- I moved the parse_item factory as a static method at ItemNode.parse.

I pushed a branch at sydneyli/apacheconfig:merged-writable-loader-item-sphinx that merges this branch with #77 to show that the docs make the apacheconfig.wloader automodule properly.

Copy link
Owner

@etingof etingof left a comment

Choose a reason for hiding this comment

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

I have some more nitpicks for your consideration. I hope you do not mind (yet). ;-)

@sydneyli
Copy link
Contributor Author

@etingof this is ready for more review, when you have time ^_^ Biggest change is moving the docs to Napoleon per your suggestion-- the docs are definitely a lot cleaner now.

@etingof
Copy link
Owner

etingof commented Oct 16, 2019

@etingof this is ready for more review, when you have time ^_^ Biggest change is moving the docs to Napoleon per your suggestion-- the docs are definitely a lot cleaner now.

Awesome! Thank you for the heads up - I've been sidetracked by the upcoming conference. I will get back to this shortly.

Copy link
Owner

@etingof etingof left a comment

Choose a reason for hiding this comment

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

I am sorry for it has taken that long!

I've done another round, I think the code is in a good shape! I have a couple of nits for your consideration.

Copy link
Owner

@etingof etingof left a comment

Choose a reason for hiding this comment

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

First of all, I am terribly sorry for long delays! But the good news is that I am hopefully back from my conference preparations!

I've posted some more nits, these are the side-effect of my trying to understand the new design. Those are mostly nits, in my mind they might be helpful for the human reader to understand the arrangements. WDYT?

I will now proceed to the next PRs.

[_restore_original(word) for word in self._raw])))


def native_apache_parser(options=None):
Copy link
Owner

@etingof etingof Oct 30, 2019

Choose a reason for hiding this comment

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

It seems that this method mainly applies some specific options to lexer/parser/config objects. In some sense, the instantiation code is not relevant to this purpose, right?

So what if we introduce some sort of syntax "flavors" i.e. sets of options, perhaps as global constants, that the user can just pick or mix and match to specialize parsing suite to the desired syntax?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I like the idea of having and exporting a set of common option configurations. Something like NATIVE_APACHE_PARSER_OPTIONS?

The motivation behind this was primarily to have a simpler interface for creating a native Apache parser-- would you prefer not to increase the surface area of exported functions to maintain? Either way is fine by me.

Copy link
Owner

@etingof etingof Oct 31, 2019

Choose a reason for hiding this comment

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

Yes, I like the idea of having and exporting a set of common option configurations. Something like NATIVE_APACHE_PARSER_OPTIONS?

Yeah... BTW, with current design the options are not only for the parser, but for lexer and loader as well.

The motivation behind this was primarily to have a simpler interface for creating a native Apache parser-- would you prefer not to increase the surface area of exported functions to maintain? Either way is fine by me.

I'd try not to introduce something overly specific and not likely reusable whenever possible.

How about this:

from apacheconfig import flavors
from apachaconfig import make_loader

with make_loader(**flavors.NATIVE_APACHE) as loader:
    ...

If we also need just parser or just lexer, would it make sense to have similar functions for them? Or may be we can rename & parameterize make_loader so that it would become a universal factory function?

Either way, this factory function(s) would be driven by pre-defined and/or user-specified options (flavors, in my snippet).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm a fan of exposing the option sets (flavors, as you put it) for the time being-- I have to think a bit more on what the factory function might look like, maybe once the other interfaces are in.

Copy link
Owner

Choose a reason for hiding this comment

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

I am thinking, that functionally we specialize parser to work on a specific kind (flavor) of grammar. Each flavor can be composed from a bunch of options.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I gave it a shot with a flavors.py-- lmk what you think!

@sydneyli
Copy link
Contributor Author

First of all, I am terribly sorry for long delays! But the good news is that I am hopefully back from my conference preparations!

No worries at all! Thanks for working with us on this :)

I've posted some more nits, these are the side-effect of my trying to understand the new design. Those are mostly nits, in my mind they might be helpful for the human reader to understand the arrangements. WDYT?

Naming is difficult, so I appreciate your input here! I think they make sense. Took your suggestions.

Copy link
Owner

@etingof etingof left a comment

Choose a reason for hiding this comment

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

The new code makes sense to me so far!

I am curious if this factory context manager:

@contextmanager
def make_loader(**options):
    ApacheConfigLexer = make_lexer(**options)
    ApacheConfigParser = make_parser(**options)

    yield ApacheConfigLoader(ApacheConfigParser(ApacheConfigLexer()),
                             **options)

Could be generalized to simplify this code:

        ApacheConfigLexer = make_lexer(**flavors.NATIVE_APACHE)
         ApacheConfigParser = make_parser(**flavors.NATIVE_APACHE)
         self.parser = ApacheConfigParser(ApacheConfigLexer(), start="contents")

@sydneyli
Copy link
Contributor Author

sydneyli commented Nov 1, 2019

Re: the make_loader context manager, could create a generic parser context manager, though probably name it something else (since make_parser already exists!) Either way, we could also punt this conversation to another issue for what sort of factory interface to provide for the writable loader.

@etingof
Copy link
Owner

etingof commented Nov 1, 2019

Re: the make_loader context manager, could create a generic parser context manager, though probably name it something else (since make_parser already exists!) Either way, we could also punt this conversation to another issue for what sort of factory interface to provide for the writable loader.

Alright, so what's remaining for this PR to be merged? My only question so far is possible repetitive parser re-creation. Is this a valid concern?

@sydneyli
Copy link
Contributor Author

sydneyli commented Nov 1, 2019

Alright, so what's remaining for this PR to be merged? My only question so far is possible repetitive parser re-creation. Is this a valid concern?

That fix should be coming in the downstream PR!

@sydneyli
Copy link
Contributor Author

sydneyli commented Nov 1, 2019

(To be specific, since the LeafNode doesn't contain any other config items, it doesn't need a reference to a parser since it doesn't do any parsing)

@etingof etingof merged commit 5741248 into etingof:master Nov 1, 2019
@etingof
Copy link
Owner

etingof commented Nov 1, 2019

Thank you! \o/

@etingof
Copy link
Owner

etingof commented Nov 1, 2019

We should probably update CHANGES at some point.

@sydneyli sydneyli deleted the writable-loader-item branch November 1, 2019 22:12
@etingof
Copy link
Owner

etingof commented Nov 1, 2019

Another unrelated thought: would it make sense to add "default" flavor essentially enumerating all options and their defaults? That won't technically change anything, but would probably be more illustrative and easier to change defaults.

@sydneyli
Copy link
Contributor Author

sydneyli commented Nov 1, 2019

I think that would be good! a lot of the defaults are scattered in the codebase (using dict.get(key, default)) so something like that would consolidate them in one place. I'll open an issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants