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

Eliminate bindings for partial pattern matches #87920

Closed
brandtbucher opened this issue Apr 6, 2021 · 5 comments
Closed

Eliminate bindings for partial pattern matches #87920

brandtbucher opened this issue Apr 6, 2021 · 5 comments
Assignees
Labels
3.10 only security fixes interpreter-core (Objects, Python, Grammar, and Parser dirs) type-feature A feature request or enhancement

Comments

@brandtbucher
Copy link
Member

BPO 43754
Nosy @gvanrossum, @markshannon, @pablogsal, @brandtbucher
PRs
  • bpo-43754: Eliminate bindings for partial pattern matches #25229
  • bpo-43754: Fix compiler warning in Python/compile.c #25855
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = 'https://github.com/brandtbucher'
    closed_at = <Date 2021-05-02.20:05:54.734>
    created_at = <Date 2021-04-06.20:00:31.366>
    labels = ['interpreter-core', 'type-feature', '3.10']
    title = 'Eliminate bindings for partial pattern matches'
    updated_at = <Date 2021-05-03.15:21:05.881>
    user = 'https://github.com/brandtbucher'

    bugs.python.org fields:

    activity = <Date 2021-05-03.15:21:05.881>
    actor = 'pablogsal'
    assignee = 'brandtbucher'
    closed = True
    closed_date = <Date 2021-05-02.20:05:54.734>
    closer = 'brandtbucher'
    components = ['Interpreter Core']
    creation = <Date 2021-04-06.20:00:31.366>
    creator = 'brandtbucher'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 43754
    keywords = ['patch']
    message_count = 5.0
    messages = ['390368', '390499', '391827', '392717', '392812']
    nosy_count = 4.0
    nosy_names = ['gvanrossum', 'Mark.Shannon', 'pablogsal', 'brandtbucher']
    pr_nums = ['25229', '25855']
    priority = 'normal'
    resolution = None
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'enhancement'
    url = 'https://bugs.python.org/issue43754'
    versions = ['Python 3.10']

    @brandtbucher
    Copy link
    Member Author

    This draft PR contains a couple of pattern matching improvements I'm experimenting with. Most significantly, it implements behavior that several people requested during the PEP-634 feedback process: no more name bindings for partial matches.

    (One caveat: all names are bound *before* evaluating the corresponding guard. If the guard fails, these bindings won't be rolled back before matching the next case.)

    In short, this is accomplished by storing captured objects on the stack underneath the more immediately important stuff, popping them all on failure or storing them all only once the *entire* pattern for that case matches. The control flow needs to be greatly simplified in order to make this work correctly, so the patch replaces the current "push bools and jump if false a bunch of times" flow with something much more efficient: jumping straight into a run of POP_TOPs on failure. We already do something very similar to this in pattern_helper_sequence_unpack (the comments in the current code explain it well).

    Parts of the new code are a bit more complex than before (especially or-patterns, which need to do a bit of juggling on the stack to reorder captured items and avoid popping important data on failure), and other parts can certainly still be improved... but I personally consider it a win to have more intuitive partial match behavior with no performance penalty.

    I thought I'd loop a few of you in on it to hear your thoughts before progressing much further.

    @brandtbucher brandtbucher added the 3.10 only security fixes label Apr 6, 2021
    @brandtbucher brandtbucher self-assigned this Apr 6, 2021
    @brandtbucher brandtbucher added interpreter-core (Objects, Python, Grammar, and Parser dirs) type-feature A feature request or enhancement 3.10 only security fixes labels Apr 6, 2021
    @brandtbucher brandtbucher self-assigned this Apr 6, 2021
    @brandtbucher brandtbucher added interpreter-core (Objects, Python, Grammar, and Parser dirs) type-feature A feature request or enhancement labels Apr 6, 2021
    @brandtbucher
    Copy link
    Member Author

    Guido informed me that Mark is currently maintaining a PEP-653 implementation branch. I checked it out today, and it looks like it has *lots* of conflicts with this one.

    For the time being, I'm going to experiment with other ways of accomplishing this that don't involve rewriting most of the pattern compiler. That way we can minimize potential merge conflicts.

    @brandtbucher
    Copy link
    Member Author

    Since the feature freeze is coming up (and this changes the bytecode), I'd like to open this up for review now.

    It probably shouldn't actually be merged before the AST changes in bpo-43892, though. There will be quite a few conflicts that need resolving, but I'd rather integrate the AST changes into this PR than force Nick to integrate these deeper changes into his branch.

    @brandtbucher
    Copy link
    Member Author

    New changeset 0ad1e03 by Brandt Bucher in branch 'master':
    bpo-43754: Eliminate bindings for partial pattern matches (GH-25229)
    0ad1e03

    @pablogsal
    Copy link
    Member

    New changeset 3949428 by Pablo Galindo in branch 'master':
    bpo-43754: Fix compiler warning in Python/compile.c (GH-25855)
    3949428

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    3.10 only security fixes interpreter-core (Objects, Python, Grammar, and Parser dirs) type-feature A feature request or enhancement
    Projects
    None yet
    Development

    No branches or pull requests

    2 participants