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

Make {eol_}comments_re read-only and non-init arguments in `ParserCon… #353

Merged
merged 9 commits into from
Jan 3, 2025

Conversation

apalala
Copy link
Collaborator

@apalala apalala commented Dec 29, 2024

…fig` (#352)

  • [buffering] drop forced multiline match for string patterns

Previously, when scanning for matches to a regex, if the type of the pattern was str, the pattern was always compiled with re.MULTILINE.

Recent changes to ParserConfig 0 changed the type used for regex matches in generated code from str to re.Pattern which could lead to a difference in behavior from previous versions where a defined comments or eol_comments may have been implicitly relying on the re.MULTILINE flag.

After discussion 1, it has been determined that usage of re flags within TatSu should be deprecated in favor of users specifying the necessary flags within patterns.

As such, drop the re.MULTILINE flag for strings compiled on the fly.

  • [grammar] make eol_comments multiline match

Make the default eol_comments regex use multiline matching.

Recent changes to ParserConfig 0 now use a precompiled regex (an re.Pattern) instead of compiling the str regex on the fly.

The Tokenizer previously assumed str type regexes should all be re.MULTILINE regardless of options defined in the regex itself when compiling the pattern. This behavior has since changed to no longer automatically apply and thus requires configurations to specify the option in the pattern.

  • [infos] make {eol_}comments_re read-only attributes

Previously, the eol_comments_re and comments_re attributes were public init arguments, were modifiable, and could thus become out of sync with the eol_comments and comments attributes.

Also, with recent changes to ParserConfig 0, there were two ways to initialize the regex values for comments and eol_comments directives; either via the constructor using the *_re variables or by using the sister string arguments and relying on __post_init__ to compile the values which trumped the explicit *_re argument values.

Now, the constructor interface has been simplified to not take either eol_comments_re or comments_re as arguments. Callers may only use eol_comments and comments.

The eol_comments_re and comments_re attributes are still public, but are read-only so they are always a reflection of their sister string values passed into the constructor.

  • [codegen] migrate to {eol_}comments

  • [ngcodegen] migrate to {eol_}comments

  • [bootstrap] migrate to {eol_}comments

  • [lint] resolve errors

  • [docs] note {eol_}comments directive behavior changes

  • [docs] update syntax to reflect {eol_}comments arguments

  • [test] fix test_parse_hash to use eol_comments

  • [test] explicitly use multiline match in test_patterns_with_newlines

…fig` (#352)

* [buffering] drop forced multiline match for string patterns

Previously, when scanning for matches to a regex, if the type of the
pattern was `str`, the pattern was always compiled with `re.MULTILINE`.

Recent changes to `ParserConfig` [0] changed the type used for regex
matches in generated code from `str` to `re.Pattern` which could lead to
a difference in behavior from previous versions where a defined comments
or eol_comments may have been implicitly relying on the `re.MULTILINE`
flag.

After discussion [1], it has been determined that usage of `re` flags
within TatSu should be deprecated in favor of users specifying the
necessary flags within patterns.

As such, drop the `re.MULTILINE` flag for strings compiled on the fly.

[0]: #338
[1]: #351 (comment)

* [grammar] make eol_comments multiline match

Make the default eol_comments regex use multiline matching.

Recent changes to `ParserConfig` [0] now use a precompiled regex (an
`re.Pattern`) instead of compiling the `str` regex on the fly.

The `Tokenizer` previously assumed `str` type regexes should all be
`re.MULTILINE` regardless of options defined in the regex itself when
compiling the pattern. This behavior has since changed to no longer
automatically apply and thus requires configurations to specify the
option in the pattern.

[0]: #338

* [infos] make {eol_}comments_re read-only attributes

Previously, the `eol_comments_re` and `comments_re` attributes were
public init arguments, were modifiable, and could thus become out of
sync with the `eol_comments` and `comments` attributes.

Also, with recent changes to `ParserConfig` [0], there were two ways to
initialize the regex values for comments and eol_comments directives;
either via the constructor using the *_re variables or by using the
sister string arguments and relying on `__post_init__` to compile the
values which trumped the explicit *_re argument values.

Now, the constructor interface has been simplified to not take either
`eol_comments_re` or `comments_re` as arguments. Callers may only use
`eol_comments` and `comments`.

The `eol_comments_re` and `comments_re` attributes are still
public, but are read-only so they are always a reflection of their
sister string values passed into the constructor.

[0]: #200

* [codegen] migrate to {eol_}comments

* [ngcodegen] migrate to {eol_}comments

* [bootstrap] migrate to {eol_}comments

* [lint] resolve errors

* [docs] note {eol_}comments directive behavior changes

* [docs] update syntax to reflect {eol_}comments arguments

* [test] fix test_parse_hash to use eol_comments

* [test] explicitly use multiline match in test_patterns_with_newlines
@vfazio
Copy link
Collaborator

vfazio commented Dec 29, 2024

I guess I should add myself to the contributors list? Or is that something you do? Otherwise the only fixups I'd make are the reference markers in the description and commit message but those aren't super important

@apalala apalala marked this pull request as draft December 29, 2024 16:33
@apalala
Copy link
Collaborator Author

apalala commented Dec 29, 2024

@vfazio, Please see the review comments.

It's not possible to merge this PR as is.

@vfazio
Copy link
Collaborator

vfazio commented Dec 29, 2024

@vfazio, Please see the review comments.

It's not possible to merge this PR as is.

Oh, sorry. I don't see any comments, but you put this in draft so I imagine you're still adding them.

Thanks for your help.

@apalala apalala marked this pull request as ready for review December 29, 2024 19:43
@apalala
Copy link
Collaborator Author

apalala commented Dec 29, 2024

@vfazio, I managed to upgrade one of my parsers to this branch, and it wasn't much work.

But we can't just go breaking who knows how many parsers by removing comments_re. We should slowly deprecate it instead.

What could be done is :

  • leave comments_re as a quasi-alias for comments
  • type comments_re as re.Pattern | str and figure things out in __post_ini__()
  • raise in ParserConfig if both comments and comments_re are defined
  • Issue a deprecation warning if comments_re is used

(the same for eol_comments )

If you can make the above changes, I'd be glad to merge. If not, I'll take care of the changes myself soon.

@vfazio
Copy link
Collaborator

vfazio commented Dec 29, 2024

@apalala I'll think on this tomorrow.

I have a feeling it's going to be complex to deal with comments being initialized from an ebnf directive and then allowing it to be overridden via comments_re via compile or whatever else passes along the settings kwargs dict. Presumably this should overwrite the comments keyword but not raise an error. An error would only be raised if both were specified in the settings kwargs dict? Otherwise we'll always be raising an error because the grammar will always define comments while legacy, non-regenerated or updated code will always specify comments_re.

What we can maybe do is perform a translation in ParserConfig.replace to translate comments_re and eol_comments_re to their sister values and then pop them out of the dict, That way we don't have to make those attributes public again and the internal plumbing doesn't have to change since it can continue to use the read-only properties (until they're dropped) completely and we don't have to worry about extending the types?

Naive impl

    def _sanitize_deprecated_options(self, **settings: Any) -> dict[str, Any]:
        for option in (("comments_re", "comments"), ("eol_comments_re", "eol_comments")):
            if not option[0] in settings:
                continue
            deprecated_option = settings[option[0]]
            del settings[option[0]]
            if deprecated_option is not None:
                warnings.warn(f"{option[0]} is deprecated in favor of {option[1]}", DeprecationWarning, 4)
                if option[1] in settings:
                    raise ValueError(f"Cannot specify {option[0]} and {option[1]} simultaneously")
                if isinstance(deprecated_option, re.Pattern):
                     settings[option[1]] = deprecated_option.pattern
                else:
                    settings[option[1]] = deprecated_option
        return settings

    def replace(self, **settings: Any) -> ParserConfig:
        overrides = self._find_common(**self._sanitize_deprecated_options(**settings))
        overrides = self._filter_non_init_fields(**overrides)
        result = dataclasses.replace(self, **overrides)
(venv) vfazio@Zephyrus:~/development/TatSu$ pytest test/grammar/directive_test.py 
============================================================================ test session starts ============================================================================
platform linux -- Python 3.12.3, pytest-8.3.4, pluggy-1.5.0
rootdir: /home/vfazio/development/TatSu
configfile: tox.ini
plugins: cov-6.0.0, flake8-1.3.0, mypy-0.10.3
collected 10 items                                                                                                                                                          

test/grammar/directive_test.py ..........                                                                                                                             [100%]

============================================================================= warnings summary ==============================================================================
test/grammar/directive_test.py: 12 warnings
  /home/vfazio/development/TatSu/tatsu/bootstrap.py:50: DeprecationWarning: comments_re is deprecated in favor of comments
    config = ParserConfig.new(

test/grammar/directive_test.py: 12 warnings
  /home/vfazio/development/TatSu/tatsu/bootstrap.py:50: DeprecationWarning: eol_comments_re is deprecated in favor of eol_comments
    config = ParserConfig.new(

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
====================================================================== 10 passed, 24 warnings in 0.28s ======================================================================

Changing bootstrap:

            comments_re='(?sm)[(][*](?:.|\\n)*?[*][)]',
            eol_comments_re='(?m)#[^\\n]*$',
            eol_comments='(?m)#[^\\n]*$',
========================================================================== short test summary info ==========================================================================
FAILED test/grammar/directive_test.py::test_whitespace_directive - ValueError: Cannot specify eol_comments_re and eol_comments simultaneously
FAILED test/grammar/directive_test.py::test_whitespace_none_directive - ValueError: Cannot specify eol_comments_re and eol_comments simultaneously
...

Otherwise, does this also mean reverting the code generation behavior? Or leave that using the new comments argument?

@apalala apalala requested a review from vfazio December 30, 2024 11:06
Continue to allow the old *_re arguments but issue a DeprecationWarning
when they are encountered and translate them into the new arguments.
@vfazio
Copy link
Collaborator

vfazio commented Dec 30, 2024

@apalala when you get a chance, can you look this over and retest that things work as you expect?

@vfazio
Copy link
Collaborator

vfazio commented Dec 30, 2024

6150d8e shouldn't be necessary. The arguments should hopefully be accepted as is if the unit test is correct.

The arguments will always be set if you make these public because setting comments will set comments_re. They will always both be set as a consequence of the vars expansion. unless they are filtered out, which they won't be because the previous commit specifically filters outs non-init'd fields. That filter would have to be adjusted to filter these out specifically if you leave these public attributes.

My last two commits should fix this and have tests that pass showing it. I'm not sure they need to be actual attributes on ParserConfig. That would only be necessary if something is actually directly mutating these values and isn't doing so via ParserConfig.new or replace

@apalala
Copy link
Collaborator Author

apalala commented Dec 30, 2024

I forgot to commit my latest changes yesterday.

For some reason I haven't understood yet, comments and comments_re always get set, even if only one of them is specified..

Backwards compatibility is important. It has been there since the origins of TatSu in Grako, over 10 years ago. Some very weird code still present in TatSu is is to secure that.

The way to deprecate is to:

  • not even mention deprecated stuff in new documentation
  • patch, patch patch
  • provide deprecation warnings

Note that ParserConfig is a recent feature that solved many annoyances in parser configuration. But imperfect as it is, it solved many problems without breaking backwards compatibility.

We're almost done with this pull request.

@vfazio
Copy link
Collaborator

vfazio commented Dec 30, 2024

For some reason I haven't understood yet, comments and comments_re always get set, even if only one of them is specified..

I think we should maybe have a discussion about that before we keep stepping on each other's implementations.

When a ParserConfig object is created, we get the following:

>>> import tatsu.infos
>>> z = tatsu.infos.ParserConfig(comments="\\d")
>>> z.comments
'\\d'
>>> z.comments_re
re.compile('\\d')

The __post_init__ compiles the comment into comments_re.

When we're performing a replace, and call dataclasses.replace, the method doesn't actually update the existing dataclass object, it creates a new instance:

>>> y = dataclasses.replace(z, **{"comments": "\\w"})
>>> hex(id(y))
'0x766bddfbcb90'
>>> hex(id(z))
'0x766bde9fc650'
>>> z == y
False
>>> y.comments_re
re.compile('\\w')
>>> z.comments_re
re.compile('\\d')

When it does so, it takes all fields marked as init=True (which is the default) of the dataclass and uses them as arguments in the constructor. That means having comments_re and eol_comments_re public and init-able arguments forces these to be passed in to the constructor during replace so you will always see comments and comments_re even if only comments_re was specified.

We have the added problem that ParserConfig.replace_config uses vars to get the list of attributes from the dataclass so it attempts to pass in all attribute values as settings. This means that even calculated values like comments_re are included in the list of values to change along with the values that drive them. So that means even if a ParserConfig was initialized with comments, then replace_config is called, comments and comments_re are in the settings dictionary.

Backwards compatibility is important. It has been there since the origins of TatSu in Grako, over 10 years ago. Some very weird code still present in TatSu is is to secure that.

My implementation prior to the latest commits should maintain backwards compatibility. I'm not sure if you tested it and found that it did not?

I was hoping the following commit would have just worked since the unittest I wrote seemed to imply it both raised deprecation warnings when appropriate and raised errors when appropriate while all other unit tests continued to pass.

75bd2dd

The goal of the commit and the design up to this point is to do the following:

  1. Make sure the properties are private to the ParserConfig dataclass so that no one can directly modify the properties without going through the proper constructor flow, ParserConfig.new or replacement interface replace and merge. Users should not be mutating the ParserConfig manually AFAICT.
  2. By making these non-initable fields, we don't have the problem with dataclasses.replace trying to set these values.
  3. By renaming these attributes from the original settings, we can identify when they're passed from a legacy source, like compile or parse vs being passed via vars expansion. see _filter_non_init_fields
  4. By building in a translation layer, we can can emit the deprecation warning and then mutate the list of arguments used to update the new ParserConfig class. see _sanitize_deprecated_options

Since these attributes on the ParserConfig should be internal only and used only by ParseContext and Buffer as far as I can see, we could probably drop these attributes from ParserConfig completely and continue to use the translation layer to set comments and eol_comments.

If nothing outside of Tatsu should be touching or manipulating attributes on ParserConfig, this becomes much more straightforward. We can just drop these properties completely and still accept comments_re and eol_comments_re as arguments to the dataclass via the translation layer in the above commit.

By dropping these attributes completely, we don't have to worry about sanitizing vars or filter out fields before calling dataclasses.replace

@vfazio
Copy link
Collaborator

vfazio commented Dec 30, 2024

Dropping them all together and updating Buffer to compile the patterns on __init__:

(venv) vfazio@vfazio4 ~/development/TatSu $ git diff
diff --git a/tatsu/buffering.py b/tatsu/buffering.py
index a64f448..30688bd 100644
--- a/tatsu/buffering.py
+++ b/tatsu/buffering.py
@@ -48,6 +48,8 @@ class Buffer(Tokenizer):
         self.text = self.original_text = text
 
         self.whitespace_re = self.build_whitespace_re(config.whitespace)
+        self.comments_re = None if not config.comments else re.compile(config.comments)
+        self.eol_comments_re = None if not config.eol_comments else re.compile(config.eol_comments)
         self.nameguard = (
             config.nameguard
             if config.nameguard is not None
@@ -268,11 +270,11 @@ class Buffer(Tokenizer):
         return self._eat_regex(self.whitespace_re)
 
     def eat_comments(self):
-        comments = self._eat_regex_list(self.config.comments_re)
+        comments = self._eat_regex_list(self.comments_re)
         self._index_comments(comments, lambda x: x.inline)
 
     def eat_eol_comments(self):
-        comments = self._eat_regex_list(self.config.eol_comments_re)
+        comments = self._eat_regex_list(self.eol_comments_re)
         self._index_comments(comments, lambda x: x.eol)
 
     def next_token(self):
diff --git a/tatsu/infos.py b/tatsu/infos.py
index b822fc5..6fbc9d6 100644
--- a/tatsu/infos.py
+++ b/tatsu/infos.py
@@ -31,9 +31,6 @@ class ParserConfig:
     start_rule: str | None = None  # FIXME
     rule_name: str | None = None  # Backward compatibility
 
-    comments_re: re.Pattern | str | None = None
-    eol_comments_re: re.Pattern | str | None = None
-
     tokenizercls: type[Tokenizer] | None = None  # FIXME
     semantics: type | None = None
 
@@ -65,27 +62,6 @@ class ParserConfig:
         if self.ignorecase:
             self.keywords = [k.upper() for k in self.keywords]
 
-        # FIXME: this check should work, but somehow both attributes seem to be always set
-        # if self.comments and self.comments_re:
-        #     raise AttributeError(
-        #         f'Both `comments` and `comments_re` defined: {self.comments!r} {self.comments_re!r}')
-        if self.comments:
-            self.comments_re = re.compile(self.comments)
-        elif self.comments_re:
-            if not isinstance(self.comments_re, re.Pattern):
-                self.comments_re = re.compile(self.comments_re)
-            self.comments = self.comments_re.pattern
-
-        # FIXME: this check should work, but somehow both attributes seem to be always set
-        # if self.eol_comments and self.eol_comments_re:
-        #     raise AttributeError('Both `eol_comments` and `eol_comments_re` defined')
-        if self.eol_comments:
-            self.eol_comments_re = re.compile(self.eol_comments)
-        elif self.eol_comments_re:
-            if not isinstance(self.eol_comments_re, re.Pattern):
-                self.eol_comments_re = re.compile(self.eol_comments_re)
-            self.eol_comments = self.eol_comments_re.pattern
-
     @classmethod
     def new(
         cls,
@@ -119,18 +95,6 @@ class ParserConfig:
         else:
             return self.replace(**vars(other))
 
-    # non-init fields cannot be used as arguments in `replace`, however
-    # they are values returned by `vars` and `dataclass.asdict` so they
-    # must be filtered out.
-    # If the `ParserConfig` dataclass drops these fields, then this filter can be removed
-    def _filter_non_init_fields(self, settings: MutableMapping[str, Any]) -> MutableMapping[str, Any]:
-        for field in [
-            field.name for field in dataclasses.fields(self) if not field.init
-        ]:
-            if field in settings:
-                del settings[field]
-        return settings
-
     def _sanitize_deprecated_options(self, settings: MutableMapping[str, Any]) -> None:
         for deprecated_option, new_option in (
             ("comments_re", "comments"),
@@ -145,8 +109,8 @@ class ParserConfig:
                     DeprecationWarning,
                     4,
                 )
-                # if new_option in settings:
-                #     raise ValueError(f"Cannot specify {deprecated_option} and {new_option} simultaneously")
+                if new_option in settings:
+                    raise ValueError(f"Cannot specify {deprecated_option} and {new_option} simultaneously")
                 if isinstance(deprecated_value, re.Pattern):
                     settings[new_option] = deprecated_value.pattern
                 elif isinstance(deprecated_value, str):
@@ -156,7 +120,7 @@ class ParserConfig:
 
     def replace(self, **settings: Any) -> ParserConfig:
         self._sanitize_deprecated_options(settings)
-        overrides = self._filter_non_init_fields(self._find_common(**settings))
+        overrides = self._find_common(**settings)
         result = dataclasses.replace(self, **overrides)
         if 'grammar' in overrides:
             result.name = result.grammar
diff --git a/test/grammar/syntax_test.py b/test/grammar/syntax_test.py
index e0badd2..1cde590 100644
--- a/test/grammar/syntax_test.py
+++ b/test/grammar/syntax_test.py
@@ -426,7 +426,6 @@ def test_deprecated_comments_override(comment, option):
         tool.parse(grammar, text, **option)
 
 
-@pytest.mark.skip
 @pytest.mark.parametrize(
     "comment,option",
     [
(venv) vfazio@vfazio4 ~/development/TatSu $ pytest
======================================================================================================== test session starts =========================================================================================================
platform linux -- Python 3.12.4, pytest-8.3.4, pluggy-1.5.0
rootdir: /mnt/development/TatSu
configfile: tox.ini
plugins: flake8-1.3.0, mypy-0.10.3
collected 147 items                                                                                                                                                                                                                  

test/ast_test.py ......                                                                                                                                                                                                        [  4%]
test/buffering_test.py .......                                                                                                                                                                                                 [  8%]
test/codegen_test.py .                                                                                                                                                                                                         [  9%]
test/diagram_test.py .                                                                                                                                                                                                         [ 10%]
test/grammar/alerts_test.py .                                                                                                                                                                                                  [ 10%]
test/grammar/constants_test.py ....                                                                                                                                                                                            [ 13%]
test/grammar/defines_test.py ...                                                                                                                                                                                               [ 15%]
test/grammar/directive_test.py ..........                                                                                                                                                                                      [ 22%]
test/grammar/error_test.py ..                                                                                                                                                                                                  [ 23%]
test/grammar/firstfollow_test.py ...                                                                                                                                                                                           [ 25%]
test/grammar/join_test.py ........                                                                                                                                                                                             [ 31%]
test/grammar/keyword_test.py ........                                                                                                                                                                                          [ 36%]
test/grammar/left_recursion_test.py .........s...s.......                                                                                                                                                                      [ 51%]
test/grammar/lookahead_test.py .                                                                                                                                                                                               [ 51%]
test/grammar/parameter_test.py ......                                                                                                                                                                                          [ 55%]
test/grammar/pattern_test.py .....                                                                                                                                                                                             [ 59%]
test/grammar/pretty_test.py ..                                                                                                                                                                                                 [ 60%]
test/grammar/semantics_test.py ....                                                                                                                                                                                            [ 63%]
test/grammar/stateful_test.py .                                                                                                                                                                                                [ 63%]
test/grammar/syntax_test.py .............................                                                                                                                                                                      [ 83%]
test/misc_test.py .                                                                                                                                                                                                            [ 84%]
test/model_test.py ..                                                                                                                                                                                                          [ 85%]
test/parser_equivalence_test.py ........                                                                                                                                                                                       [ 91%]
test/parsing_test.py ........                                                                                                                                                                                                  [ 96%]
test/pickle_test.py ..                                                                                                                                                                                                         [ 97%]
test/walker_test.py ..                                                                                                                                                                                                         [ 99%]
test/zzz_bootstrap/bootstrap_test.py .                                                                                                                                                                                         [100%]

================================================================================================== 145 passed, 2 skipped in 13.96s ===================================================================================================

@apalala
Copy link
Collaborator Author

apalala commented Dec 30, 2024

Dropping them all together and updating Buffer to compile the patterns on __init__:

I don't understand...

@vfazio
Copy link
Collaborator

vfazio commented Dec 30, 2024

Dropping them all together and updating Buffer to compile the patterns on __init__:

I don't understand...

We can drop the attributes completely from ParserConfig with no ill effect if we update Buffer and ParseContext.

These are the only two places that use the eol_comments_re and comments_re attributes off of the ParserConfig. There's no reason why these patterns have to be compiled attributes on the ParserConfig. In fact, compiling the pattern in __post_init__ is kind of a waste given how many times new dataclasses are created as new settings are passed around over and over.

#338 was the PR that decided these needed to be compiled. Up until this PR, the values of eol_comments_re and comments_re were just the string patterns.

There's no reason why Buffer needs to reference the precompiled pattern. Buffer can simply query the directive off of the ParserConfig and compile the pattern itself in __init__ as necessary to avoid the performance problem that PR was trying to avoid, which was the constant compilation of strings patterns when used in Buffer.eat_comments

We don't document return types on ParseContext but that PR did change the return type of ParseContext.eol_comments_re to be something that may be unsupported by users since up until that MR only a str or None was returned. I don't know how this class is used. There is no unit test that tests these properties of ParseContext. That PR introduced a potentially non-backwards compatible change

If these have to be available off the class, which I'm not sure they do but I'll defer to you, then we can mark those as deprecated properties:

    @property
    def comments_re(self) -> str | None:
        warnings.warn(f"{self.__class__.__name__}.comments_re is deprecated", DeprecationWarning, 1)
        return self.comments

    @property
    def eol_comments_re(self) -> str | None:
        warnings.warn(f"{self.__class__.__name__}.eol_comments_re is deprecated", DeprecationWarning, 1)
        return self.eol_comments

This still avoids them being direct attributes on the ParserConfig class so still avoids the problem with dataclasses.replace and vars.

@apalala
Copy link
Collaborator Author

apalala commented Jan 2, 2025

@vfazio

I thought about it, and I agree that we should just drop comments_re and eol_comments_re.

We could keep them on ParserConfig for one release just to raise an exception with an explanatory message.

Some parsers will break, but the fix is extremely easy.

I'll make the changes now for your review.

@vfazio
Copy link
Collaborator

vfazio commented Jan 2, 2025

I'm on holiday until next week. I had planned on summarizing this issue so we could discuss a path forward. The challenge here is I'm an outsider and am not familiar with how this library is used.

I want to make sure we're both talking about the same thing.

From what I understand, you want to continue to allow things like parser = compile(grammar, eol_comments_re='')

I think this fine and 100% doable.

It does not require having the attributes on ParserConfig however. I see no need to keep those attributes unless someone outside of the library is directly using the ParserConfig object.

We can continue to support those settings arguments because the interface is not strictly typed. That's what my commit did, it just translates those arguments to the new attributes.

My commit could be simplified further by dropping the legacy attributes (the diff I posted) since, at least from my reading of the code, they aren't necessary anymore. The unit tests showed this at least and it passed the test I added which checks for conversion of the legacy arguments.

I can either submit my suggested fixups on Monday, or you can proceed as you see fit and I will review them, though I'm not sure how useful my input will be.

@apalala
Copy link
Collaborator Author

apalala commented Jan 3, 2025

@vfazio Take a look at the latest commits when you have time.

What I've done is leave commons_re defined, but raise if it's used with a message explaining what's happening.

We can retake this issue with a new pull request, in time.

@apalala apalala merged commit 0240667 into master Jan 3, 2025
2 checks passed
@apalala apalala deleted the drop_comments_re branch January 13, 2025 21:42
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.

2 participants