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

Fix formatting cells with magic methods and starting or trailing empty lines #4484

Merged
merged 4 commits into from
Oct 14, 2024

Conversation

AleksMat
Copy link
Contributor

@AleksMat AleksMat commented Oct 14, 2024

Description

This PR fixes an issue where Jupyter cells containing any magic method and at least 1 empty line at the start or at the end of the cell don't get formatted at all.

This is an example of a cell that doesn't get formatted:



%time
a=1


But if there are no magic methods then formatting works. The following cell:



#No magic methods
a=1


gets correctly reformatted into:

# No magic methods
a = 1

It turns out the problem is in black.handle_ipynb_magics.mask_cell function:

  1. The call to TransformerManager.transform_cell returns a result without empty lines at the beginning of the cell. Because this part is implemented in ipython I didn't investigate why this is the case.

  2. The call to replace_magics returns a result without empty lines at the end of the cell. This is because the implementation of replace_magics assumes that

    "\n".join(src.splitlines())

    will always produce src again. This is not the case, e.g. "\n".join("\n\n".splitlines()) returns "\n".

  3. Because of 1. and 2. the check len(transformed.splitlines()) != len(src.splitlines()) is triggered and NothingChanged is raised.

Solution

  1. A comment about TransformerManager.transform_cell removing empty lines. Future improvements in ipython are possible.
  2. Minor update in replace_magics so that it won't be removing empty lines at the end anymore.
  3. The number of lines in transformed and src should be compared without starting and ending empty lines. Hence len(transformed.strip().splitlines()) != len(src.strip().splitlines())

I also added a few unit tests that test such cases.

Checklist - did you ...

  • Add an entry in CHANGES.md if necessary?
  • Add / update tests if necessary?
  • Add new / update outdated documentation?

Copy link
Collaborator

@JelleZijlstra JelleZijlstra left a comment

Choose a reason for hiding this comment

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

Thanks!

CHANGES.md Outdated Show resolved Hide resolved
@JelleZijlstra JelleZijlstra merged commit fff747d into psf:main Oct 14, 2024
46 checks passed
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.

2 participants