Erotemic / xdoctest

A rewrite of Python's builtin doctest module (with pytest plugin integration) with AST instead of REGEX.
Apache License 2.0
205 stars 12 forks source link

Fails the test because of the quote style. #130

Closed rgreinho closed 2 years ago

rgreinho commented 2 years ago

I have simple wrapper function to the US census library:

def state_info(state):
    """
    Given a the full name of a state, returns the corresponding abbreviation and FIPS code.

    Example:

    >>> state_info("texas")
    ("TX", "48")
    """
    abbrev = states.mapping("name", "abbr").get(state.title())
    st = states.lookup(abbrev)
    fips = st.fips
    return (abbrev, fips)

However xdoctest fails because the of quoting style:

DOCTEST PART BREAKDOWN
Failed Part:
    2 >>> state_info("texas")
DOCTEST TRACEBACK
Expected:
    ("TX", "48")
Got:
    ('TX', '48')
Repr Difference:
    got  = "('TX', '48')"
    want = '("TX", "48")'

Since the expected value matches my output, I thought the test would pass.

rgreinho commented 2 years ago

This issue may actually be related to #87.

Erotemic commented 2 years ago

Yup, you would need implement a new fuzzy check.

My recommendation is to use single quotes as they are IMHO superior (despite what black thinks), and that's what Python's repr emits. But I will accept a PR that adds this fuzzy check.

rgreinho commented 2 years ago

Since I cannot switch the black configuration for the whole team, I may have to give a shot at this fuzzy check.

Could you provide a few pointers to help me start?

Erotemic commented 2 years ago

FWIW, the style of the expected "want" string isn't enforced by black, and it would be more accurate to use the quoting style there that the actual Python interpreter outputs. Also, there is nothing stopping you from simply writing:

def state_info(state):
    """
    Given a the full name of a state, returns the corresponding abbreviation and FIPS code.

    Example:

    >>> assert state_info("texas") == ("TX", "48")
    """
    abbrev = states.mapping("name", "abbr").get(state.title())
    st = states.lookup(abbrev)
    fips = st.fips
    return (abbrev, fips)

And that has the advantage that it can be refactored as a unit test verbatim. The other alternative - if you simply want this for more documentation purposes, is to remove the check entirely and rely on unit tests to actually check cases:

def state_info(state):
    """
    Given a the full name of a state, returns the corresponding abbreviation and FIPS code.

    Example:

    >>> state_info("texas")  # xdoctest: +IGNORE_WANT
    ("TX", "48")
    """
    abbrev = states.mapping("name", "abbr").get(state.title())
    st = states.lookup(abbrev)
    fips = st.fips
    return (abbrev, fips)

But if you want to extend the checker, all of the logic lives here:

https://github.com/Erotemic/xdoctest/blob/main/src/xdoctest/checker.py

It probably also makes sense to add a directive:

https://github.com/Erotemic/xdoctest/blob/main/src/xdoctest/directive.py

which is disabled by default (maybe call it NORMALIZE_QUOTES?) and can be specified to enable this behavior.

rgreinho commented 2 years ago

Thank you very much! I did use the first alternative you suggested and it worked like a charm. 👍