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

Add pyproject.toml support #7247

Merged
merged 16 commits into from
Jun 8, 2020
Merged

Conversation

nicoddemus
Copy link
Member

@nicoddemus nicoddemus commented May 23, 2020

Fix #1556

@nicoddemus
Copy link
Member Author

(the code is ready for review I believe, keeping as draft because I need to update the docs)

@nicoddemus nicoddemus force-pushed the pyproject.toml branch 2 times, most recently from ae2d84a to a746cc4 Compare June 2, 2020 18:54
@nicoddemus nicoddemus marked this pull request as ready for review June 2, 2020 19:04
@nicoddemus
Copy link
Member Author

(py35 failures might be related to #7303)

Copy link
Member

@asottile asottile left a comment

Choose a reason for hiding this comment

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

change looks good otherwise!

doc/en/customize.rst Show resolved Hide resolved

Initialization: determining rootdir and inifile
-----------------------------------------------
Initialization: determining rootdir and configfile
Copy link
Member

Choose a reason for hiding this comment

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

do we want to preserve external links to this target?

Copy link
Member Author

@nicoddemus nicoddemus Jun 4, 2020

Choose a reason for hiding this comment

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

I don't really think it is necessary... we've changed section titles in the past. Or is there a way to preserve the old link that I'm not aware of?

Copy link
Member

@bluetech bluetech left a comment

Choose a reason for hiding this comment

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

Left some comments on the code. I've yet to read to issue to try to understand the ini_options approach but I get a sense of why it was done...

doc/en/reference.rst Show resolved Hide resolved
src/_pytest/config/__init__.py Show resolved Hide resolved
src/_pytest/config/findpaths.py Outdated Show resolved Hide resolved
src/_pytest/config/findpaths.py Outdated Show resolved Hide resolved
src/_pytest/config/findpaths.py Outdated Show resolved Hide resolved

result = config.get("tool", {}).get("pytest", {}).get("ini_options", None)
if result is not None:
# convert all scalar values to strings for compatibility with other ini formats
Copy link
Member

Choose a reason for hiding this comment

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

Should this be recursive? Otherwise I can write e.g. addopts = [true, 10].

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't think so, that's invalid in TOML:

>>> import toml
>>> toml.loads('x = [true, 10]')
...
ValueError: Not a homogeneous array
>>> toml.loads('x = [10, 20]')
{'x': [10, 20]}

Recursive arrays are a possibility:

>>> toml.loads('x = [[10, 20], [30, 40]]')
{'x': [[10, 20], [30, 40]]}

But I would rather be safe here and convert them to string anyway, because that's what we would have gotten if we wrote that in an ini file.

# convert all scalar values to strings for compatibility with other ini formats
# conversion to actual useful values is made by Config._getini
def make_scalar(v):
return v if isinstance(v, (list, tuple)) else str(v)
Copy link
Member

Choose a reason for hiding this comment

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

Does toml actually give out both list and tuple? Would have assumed it's only one.

What about dicts?

dates and datetimes can also be unexpected, but I guess their str is fine.

Copy link
Member Author

Choose a reason for hiding this comment

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

You are right, fixed to only test for lists.

Everything else should be converted to strings I think, because that's what we would have gotten if we wrote them in an ini file. The tool.pytest.ini_options is a bridge to configure pytest using pyproject.toml files with the legacy options, hopefully we can in the future thinks of better ways to make advantage of the more powerful features of TOML.


def _get_ini_config_from_pyproject_toml(
path: py.path.local,
) -> Optional[Dict[str, Any]]:
Copy link
Member

Choose a reason for hiding this comment

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

Basically IIUC we want the Any here to be Union[None, str, List[str]].

Copy link
Member Author

Choose a reason for hiding this comment

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

I've changed to Union[str, List[str]], because I don't think TOML supports None?

return None


def getcfg(args):
Copy link
Member

Choose a reason for hiding this comment

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

Would be great if you're able to type-annotate this one 😁 Usually I don't ask this but in this case I think it can really be beneficial for clarifying things.

Copy link
Member Author

Choose a reason for hiding this comment

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

No worries, feel free to ask anytime... but I just did it, and yikes!

def getcfg(args: List[Union[str, py.path.local]]) -> Tuple[Optional[py.path.local], Optional[py.path.local], Optional[Dict[str, Union[str, List[str]]]]]:

Feel free to suggest how to improve readability here.

Copy link
Member 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 go there, let me know if you have any suggestions however. 👍

Copy link
Member

@RonnyPfannschmidt RonnyPfannschmidt left a comment

Choose a reason for hiding this comment

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

'

@nicoddemus
Copy link
Member Author

Noticed also -c is not being handled correctly yet. Will need a bit more of time to work out the kinks.

@nicoddemus
Copy link
Member Author

Rebased and did further refactorings in findpaths.py to be able to make -c somefile.toml to work.

Copy link
Member

@bluetech bluetech left a comment

Choose a reason for hiding this comment

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

Great work @nicoddemus, besides adding the new feature, the code in findpaths.py is much cleaner than before.

I agree that the approach taken is a decent way to support pyproject.toml in the midterm without too many consequences for the future or big code changes.

Personally I'd prefer "tool.pytest.ini" over "tool.pytest.ini_options".

I'd also add a short "note" comment in the documentation to explain why it's "pytest.tool.ini_options" and not just "tool.pytest" -- it's seems odd if unexplained.

There's also some type errors that come up when checking with proper py.path.local typing (pytest-dev/py#232), but there are also existing errors so I need to take care of that myself anyway.

src/_pytest/config/findpaths.py Outdated Show resolved Hide resolved
src/_pytest/config/findpaths.py Outdated Show resolved Hide resolved
src/_pytest/config/findpaths.py Outdated Show resolved Hide resolved
src/_pytest/config/findpaths.py Outdated Show resolved Hide resolved
src/_pytest/config/findpaths.py Outdated Show resolved Hide resolved
@nicoddemus
Copy link
Member Author

I'd also add a short "note" comment in the documentation to explain why it's "pytest.tool.ini_options" and not just "tool.pytest" -- it's seems odd if unexplained.

Done!

@nicoddemus nicoddemus requested a review from aklajnert June 7, 2020 12:56
@nicoddemus nicoddemus changed the title pyproject.toml support Add pyproject.toml support Jun 8, 2020
@nicoddemus nicoddemus merged commit c17d508 into pytest-dev:master Jun 8, 2020
@nicoddemus nicoddemus deleted the pyproject.toml branch June 8, 2020 13:03
@bluetech
Copy link
Member

@nicoddemus Re. my comment above

Personally I'd prefer "tool.pytest.ini" over "tool.pytest.ini_options".

Not sure if you missed it or rejected it (which is fine of course).

Just seems to me the _options part is redundant.

@nicoddemus
Copy link
Member Author

Hi @bluetech

Oh sorry, didn't mean to seem dismissive, I thought you had seen this comment: #7247 (comment)

That's what we had agreed on the original 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.

implement support for PEP-518 - the tool.pytest key in pyproject.toml
5 participants