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

Support readme files #58

Merged
merged 3 commits into from
Aug 20, 2023
Merged

Support readme files #58

merged 3 commits into from
Aug 20, 2023

Conversation

diazona
Copy link
Owner

@diazona diazona commented Aug 14, 2023

This pull request adds support for readme files, populated by what setuptools calls the long description. This one is a bit more complicated because the naive way to get the field value, get_long_description(), reads the content of the readme file if one is specified, but we need the actual filename to write into pyproject.toml, so I went a little deep into the Distribution metadata to find the raw value.

The other notable thing about this bit of code is that it will actually write the long description to a file if it was hard-coded in the setuptools parameters. This is the first case in which the plugin generates something other than the content of a pyproject.toml file.

@diazona diazona added enhancement New feature or request setuptools-fields Fields in the pyproject data structure that this project needs to support labels Aug 14, 2023
@diazona diazona added this to the Initial release milestone Aug 14, 2023
@diazona diazona self-assigned this Aug 14, 2023
@diazona
Copy link
Owner Author

diazona commented Aug 16, 2023

This caused a failure in local testing lol

$ python3.6
Python 3.6.15 (default, Jan  3 2022, 03:00:17) 
[GCC 10.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import mimetypes
>>> mimetypes.guess_extension("text/plain")
'.bat'

🤯 🤦 🤦

Apparently it affects Python <3.8

@sjlongland
Copy link
Collaborator

This caused a failure in local testing lol

$ python3.6
Python 3.6.15 (default, Jan  3 2022, 03:00:17) 
[GCC 10.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import mimetypes
>>> mimetypes.guess_extension("text/plain")
'.bat'

🤯 🤦 🤦

Apparently it affects Python <3.8

.bat eh? Blast from the past. Given it's implicated in old Python releases, that are no longer maintained, I don't see them fixing it upstream anytime soon.

The readme field in pyproject.toml is populated from long_description
and long_description_content_type (if present) in the setuptools
configuration. This one is a little complicated though, because calling
Distribution.get_long_description() will just return the text content of
the long description, whereas what we need to write into pyproject.toml
is the name of a file containing (what setuptools calls) the long
description - in other words, the name of the readme file.

What I've done here to handle that is dig into the more obscure fields
of the Distribution object to find where it stores the original, raw
value of the long_description field, and if that field starts with
`file:`, I extract the filename and copy it over into pyproject.toml.
On the other hand, if the long_description is a string, I've made it
write that string out to a file and put the filename in pyproject.toml.
The file is named with an extension corresponding to the content type
if available; I introduced a bit of custom code to find the extension
for a given content type to work around a bug in older versions of
Python.

This makes the plugin do something that has not been done for any
previous field, namely creating a brand new file that needs to become
part of the project being converted. I'm not sure how best to handle
this. The current implementation is fine to get something that basically
works, but it might be better to issue some kind of a warning or
notification to the user that a new file was created, or perhaps exit
with an error that prompts the user to explicitly specify that it's okay
to write a new file with a command-line option. (Maybe that option could
accept the new filename as an argument.) We should probably revisit this
in the future based on what seems to be most useful.

The content type is a bit more straightforward: I can just copy it from
setuptools into the pyproject data structure, if it's there, and if not
I just use a string value for the `readme` field. I have not made any
effort to have the code guess the content type based on the content of
the long description. That's something we could potentially add in
the future, but it's going beyond what I have in mind as the purpose of
this plugin, which is to copy information from setuptools to
pyproject.toml as faithfully as possible.
These tests exercise a variety of configurations of the readme field
in pyproject.toml: with or without a content type, referring to
an existing file or a new one that the plugin has to create, and with
various file types/extensions.
This commit adds the expected result for the readme field to
test_everything(). I also stuck in a content type so that the input
includes as many fields as possible (since that's the point of
the test).
@diazona diazona marked this pull request as ready for review August 20, 2023 01:28
@diazona diazona enabled auto-merge August 20, 2023 01:29
@diazona diazona requested a review from sjlongland August 20, 2023 01:29
@diazona diazona assigned sjlongland and unassigned diazona Aug 20, 2023
@diazona
Copy link
Owner Author

diazona commented Aug 20, 2023

I know I had mentioned adding tests that use setup.py directly in a separate discussion, but I kind of want to just get this merged without them and go back and add such tests later. (Even though the readme handling really should have such tests, because it digs into the setuptools data structures)

@diazona diazona merged commit e8ff642 into main Aug 20, 2023
@diazona diazona deleted the readme/1/dev branch August 20, 2023 03:00
@sjlongland
Copy link
Collaborator

That makes sense… I would have thought setuptools would behave the same way in both cases, but it seems you can get different behaviour depending on which method a project uses.

We didn't know this at the start… we've only just discovered that little gem. We'll come back to the inline case later I think.

@diazona diazona linked an issue Aug 20, 2023 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request setuptools-fields Fields in the pyproject data structure that this project needs to support
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support readme
2 participants