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

[MRG] Add tiny BIDS test dataset, fix doctests, and run it in CI #831

Merged
merged 27 commits into from
Jul 14, 2021

Conversation

sappelhoff
Copy link
Member

@sappelhoff sappelhoff commented Jul 6, 2021

follow up to #828
closes #829

This adds a tiny (800kb) BIDS dataset to a new tests/data directory for testing purposes.

Code for generating the data is shipped in mne_bids/tests/data/tiny_bids/code/make_tiny_bids_dataset.py, this dataset should be easily extensible in the future to add MEG, MRIs, iEEG, etc. when the need for it arises.

I make use of that dataset in the doctests, which I fix in this PR and "turn on" in CI checks.

I also use that dataset in an example, fixing #829

Adding the example dataset also showed me in its git diff that we have been writing TSV files without newline characters, violating UNIX/POSIX standards 😉 I remedied that.

Finally, this PR contains 3 "fixes" where I change json.dump to our internal _write_json, thereby simplifying some lines.

The diff is large, but most of it is the newly added data.

Merge checklist

Maintainer, please confirm the following before merging:

  • All comments resolved
  • This is not your own PR
  • All CIs are happy
  • PR title starts with [MRG]
  • whats_new.rst is updated
  • PR description includes phrase "closes <#issue-number>"

mne_bids/path.py Outdated Show resolved Hide resolved
@agramfort
Copy link
Member

+1 for pytest --doctest-modules

is it a lot of work?

@sappelhoff
Copy link
Member Author

is it a lot of work?

Maybe 🤔 Let's see, I'll work on this a bit in the next days.

@codecov-commenter
Copy link

codecov-commenter commented Jul 7, 2021

Codecov Report

Merging #831 (d09a1c9) into main (2d8a721) will increase coverage by 0.41%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #831      +/-   ##
==========================================
+ Coverage   94.17%   94.58%   +0.41%     
==========================================
  Files          23       23              
  Lines        3123     3123              
==========================================
+ Hits         2941     2954      +13     
+ Misses        182      169      -13     
Impacted Files Coverage Δ
mne_bids/inspect.py 98.74% <ø> (ø)
mne_bids/write.py 96.13% <ø> (ø)
mne_bids/path.py 97.00% <100.00%> (+<0.01%) ⬆️
mne_bids/sidecar_updates.py 98.63% <100.00%> (-0.04%) ⬇️
mne_bids/tsv_handler.py 100.00% <100.00%> (ø)
mne_bids/commands/mne_bids_report.py 17.64% <0.00%> (+17.64%) ⬆️
mne_bids/commands/run.py 34.48% <0.00%> (+34.48%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 2d8a721...d09a1c9. Read the comment docs.

@sappelhoff
Copy link
Member Author

I think the problem is that many examples rely on us having some files. So I'd have to "skip" executing most of the examples, which defeats the purpose. I think a solution would be to "ship" a tiny BIDS dataset as part of the test directory that we can use to actually execute the examples.

WDYT @hoechenberger @agramfort ?

@agramfort
Copy link
Member

agramfort commented Jul 7, 2021 via email

@sappelhoff
Copy link
Member Author

how would you "ship" it?

  1. just putting it there ... like the data in MNE-Python's IO module
  2. as a git submodule ... so that getting it is optional (unless you want to run tests)
  3. ... do you have another idea?

@agramfort
Copy link
Member

agramfort commented Jul 7, 2021 via email

@sappelhoff sappelhoff changed the title [WIP] Fix doctests (and run in CI?) [WIP] Add tiny BIDS test dataset, fix doctests, and run it in CI Jul 7, 2021
@sappelhoff sappelhoff added this to the 0.8 milestone Jul 8, 2021
@sappelhoff sappelhoff mentioned this pull request Jul 9, 2021
@sappelhoff sappelhoff marked this pull request as ready for review July 13, 2021 18:25
@sappelhoff sappelhoff changed the title [WIP] Add tiny BIDS test dataset, fix doctests, and run it in CI [MRG] Add tiny BIDS test dataset, fix doctests, and run it in CI Jul 13, 2021
we did not do that before either, but --doctest-modules is now ON

and that option apparently also runs the examples
@hoechenberger
Copy link
Member

@sappelhoff Apparently you forgot one or two places? @ CI failing

@sappelhoff
Copy link
Member Author

one is about bids_path.root, which can return a str OR a Path --> In this case it returns a Path, and on Windows this happens to be a WindowsPath, not posix. 🤷‍♂️

The other one, I am still investigating

@hoechenberger
Copy link
Member

The other one, I am still investigating

I think it's because in the test you're comparing to a path constructed via os.path.join(), which will use \\ as separator by default on Windows.

@hoechenberger
Copy link
Member

one is about bids_path.root, which can return a str OR a Path

Wait, why is that? IMHO it should always be a path …

@sappelhoff
Copy link
Member Author

Wait, why is that? IMHO it should always be a path …

yes, also according to the attributes docs in the docstr. But see:

mne-bids/mne_bids/path.py

Lines 442 to 449 in 2d8a721

@property
def root(self) -> Optional[Union[str, Path]]:
"""The root directory of the BIDS dataset."""
return self._root
@root.setter
def root(self, value):
self.update(root=value)

I am a little confused by that Union(str, Path)

@sappelhoff
Copy link
Member Author

sappelhoff commented Jul 14, 2021

Maybe the solution is:

    def __repr__(self):
        """Representation in the style of `pathlib.Path`."""
        return f'{self.__class__.__name__}(\n' \
-              f'root: {self.root}\n' \
+              f'root: {self.root.as_posix()}\n' \
               f'datatype: {self.datatype}\n' \
               f'basename: {self.basename})'

but root can be "None" 🤔

@sappelhoff
Copy link
Member Author

I think there is something I don't understand in

mne-bids/mne_bids/path.py

Lines 442 to 449 in 2d8a721

@property
def root(self) -> Optional[Union[str, Path]]:
"""The root directory of the BIDS dataset."""
return self._root
@root.setter
def root(self, value):
self.update(root=value)

  1. BIDSPath has an attribute "root" ... here defined with the @property decorator
  2. the type hints show us it can return str or Path ... Is this an error? I think it should be Path and None ... never str
  3. then it returns self._root, which is being set in the update method and is either None, or Path(val).expanduser(), where val is either Path or str
  4. the setter is fine again: calling bids_path.root = Path("/home/bids_ds") (or with None, or a str) just calls "update" method again as in the step before

@sappelhoff
Copy link
Member Author

Do we need a __str__ method for attributes? the bids_path.root attribute is just printed "as is" (a Path) 😕 ❓

@hoechenberger
Copy link
Member

  1. BIDSPath has an attribute "root" ... here defined with the @property decorator
  2. the type hints show us it can return str or Path ... Is this an error? I think it should be Path and None ... never str
  3. then it returns self._root, which is being set in the update method and is either None, or Path(val).expanduser(), where val is either Path or str

Considering point 3, I would agree that the type hint is incorrect and should be Optional[Path]

@sappelhoff
Copy link
Member Author

Considering point 3, I would agree that the type hint is incorrect and should be Optional[Path]

mmh okay - but it could be None though. What do you think of 459c723 ?

BTW: the errors are now fixed. I circumvented the repr/str issue for bids_path attributes by calling .as_posix on them in the example. I feel like further improving this should be a future PR (I am exhausted with this one)

@hoechenberger
Copy link
Member

Do we need a __str__ method for attributes? the bids_path.root attribute is just printed "as is" (a Path) 😕 ❓

we'd only need it for root, right? All other parts of the BIDSPath are strings or None anyway?
How would we do that? Would we need a new class _BIDSRoot or something?

@hoechenberger
Copy link
Member

Considering point 3, I would agree that the type hint is incorrect and should be Optional[Path]

mmh okay - but it could be None though. What do you think of 459c723 ?

Optional[foo] is just shorthand for Union[foo, None].

In Python 3.10 we'll be able to simply write foo | None like in TypeScript, but … well, we're not quite there yet.

But your proposal in 459c723 is redundant; you can safely switch to Optional[Path] (more "idiomic") or Union[Path, None] (more explicit, but rather uncommon as far as I can tell)

@sappelhoff
Copy link
Member Author

Thanks for the hint, will push a commit!

@hoechenberger
Copy link
Member

Thanks for the hint

☝️ I see what you did there! 😎

@hoechenberger
Copy link
Member

we'd only need it for root, right? All other parts of the BIDSPath are strings or None anyway?
How would we do that? Would we need a new class _BIDSRoot or something?

How about we always store BIDSPath.root as a string (str(Path(root).expanduser()) or something) and whenever we need it to concat a path, we just cat it to a Path again?

@sappelhoff
Copy link
Member Author

How about we always store BIDSPath.root as a string (str(Path(root).expanduser()) or something) and whenever we need it to concat a path, we just cat it to a Path again?

Can we store it as a Path(root).as_posix() (posix str) and then later on call Path on that posix_str and it's work on Windows? If yes, that seems like a good way to go

@hoechenberger
Copy link
Member

Can we store it as a Path(root).as_posix() (posix str) and then later on call Path on that posix_str and it's work on Windows? If yes, that seems like a good way to go

Nice idea, I think this could work

@sappelhoff
Copy link
Member Author

Ok cool, I opened a new issue for it :-)

Please merge this one if you are happy @hoechenberger

I could then do the release next.

@hoechenberger hoechenberger merged commit 0db039f into mne-tools:main Jul 14, 2021
@hoechenberger
Copy link
Member

Thanks a bunch, @sappelhoff!

@sappelhoff sappelhoff deleted the fix/doctests branch July 14, 2021 11:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

bidspath example contains runtimewarning
4 participants