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

Replace usage of cgi.parse_header() (slated for removal in 3.13) #2066

Closed
vytas7 opened this issue May 18, 2022 · 3 comments · Fixed by #2217
Closed

Replace usage of cgi.parse_header() (slated for removal in 3.13) #2066

vytas7 opened this issue May 18, 2022 · 3 comments · Fixed by #2217

Comments

@vytas7
Copy link
Member

vytas7 commented May 18, 2022

PEP 594 specifies removal of "dead batteries" in CPython 3.13, with deprecation announced in 3.11.

Apparently, cgi is also on the chopping block, so we'll have to replace cgi.parse_header(). At first glance, the suggested replacement (instantiating an email.message.Message) looks clunky and likely to perform worse. Maybe we can reimplement it in Cython instead?

@vytas7 vytas7 added this to the Version 4.x milestone May 18, 2022
@vytas7 vytas7 mentioned this issue May 22, 2022
8 tasks
@mikael-epigram
Copy link

As an alternative why not just use the cgi sourcecode. It seems quite standalone?

https://github.com/python/cpython/blob/3.11/Lib/cgi.py#L238

def _parseparam(s):
    while s[:1] == ';':
        s = s[1:]
        end = s.find(';')
        while end > 0 and (s.count('"', 0, end) - s.count('\\"', 0, end)) % 2:
            end = s.find(';', end + 1)
        if end < 0:
            end = len(s)
        f = s[:end]
        yield f.strip()
        s = s[end:]

def parse_header(line):
    """Parse a Content-type like header.
    Return the main content-type and a dictionary of options.
    """
    parts = _parseparam(';' + line)
    key = parts.__next__()
    pdict = {}
    for p in parts:
        i = p.find('=')
        if i >= 0:
            name = p[:i].strip().lower()
            value = p[i+1:].strip()
            if len(value) >= 2 and value[0] == value[-1] == '"':
                value = value[1:-1]
                value = value.replace('\\\\', '\\').replace('\\"', '"')
            pdict[name] = value
    return key, pdict

@vytas7
Copy link
Member Author

vytas7 commented Nov 17, 2022

Hi @mikael-epigram, and thanks for reaching out!
At a glance this doesn't look very performant, we'll try to write a faster version in both Python (for PyPy) and Cython. But yes, in a pinch, just vendoring this snippet would do.

@mikael-epigram
Copy link

I agree that it does not seem that performant, but that is what you are already using on CPython

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

Successfully merging a pull request may close this issue.

2 participants