-
-
Notifications
You must be signed in to change notification settings - Fork 9.5k
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
MAINT: Do not use deprecated mktemp()
#18958
Conversation
mktemp()
usage in testsmktemp()
mktemp()
mktemp()
One difference between |
In the original code when With the use of Would it be safer to use a context manager to explicitly close the file before deleting it? |
These days I think a pytest |
We used pytest
that already deletes everything. Does that make sense? |
That sounds right. It's not impossible that a |
numpy/core/tests/test_multiarray.py
Outdated
def test_empty_files_text(self, tmp_filename): | ||
with open(self.filename, 'w') as f: | ||
pass | ||
y = np.fromfile(self.filename) | ||
assert_(y.size == 0, "Array not empty") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would suggest a deeper refactoring, using pytest's tmp_file
with no extra fixtures needed in the class setup or teardown. Doesn't this work:
def test_empty_files_text(self, tmp_filename): | |
with open(self.filename, 'w') as f: | |
pass | |
y = np.fromfile(self.filename) | |
assert_(y.size == 0, "Array not empty") | |
def test_empty_files_text(self, tmp_file): | |
with open(tmp_file, 'w') as f: | |
pass | |
y = np.fromfile(tmp_file) | |
assert_(y.size == 0, "Array not empty") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mattip, unless I'm mistaken, tmp_file
is not a built-in pytest fixture. You can try by running this dummy test:
def test_foobar(tmp_file):
pass
It will fail because the fixture does not exist.
Besides, if such built-in fixture existed, it would probably also create the file on disk which is something we don't want for the tests. We only want a filename without pre-creating the file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh, my bad. It is tmp_path
not tmp_file
which gives you a PathLib object pointing to a directory like /tmp/pytest-of-matti/pytest-8/test_foobar0
where each invocation of pytest will increment the pytest-8
part and delete old ones according to some logic, and test_foobar0
is the name of the test with a 0 for good measure. So this test would be
def test_empty_files_text(self, tmp_path):
with open(tmp_path / 'empty', 'w') as f:
pass
y = np.fromfile(tmp_path / 'empty')
assert_(y.size == 0, "Array not empty")
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, but if tmp_path
is used directly, then all references to self.filename
must be removed. Another benefit of the custom fixture tmp_filename
is that it is parametrized to cover two cases with very low effort (filename
is a str
or filename
is a path-like object). Doing so allows to combine at least two tests into one test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
all references to self.filename must be removed
Sounds like a win to me, I am not a big fan of attributes that are overridden for each test. self.something
should be a persistent attribute. If it is something temporary for each test then it should be an argument of the test function.
numpy/core/tests/test_multiarray.py
Outdated
shutil.rmtree(self.tempdir) | ||
yield | ||
delattr(self, "dtype") | ||
delattr(self, "x") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think setup/teardown
is a better paradigm here than using a yield
like this. Why do you want to re-create dtype
and x
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think
setup/teardown
is a better paradigm here than using ayield
like this.
It was my understanding that setup
/teardown
is an anti-pattern when using pytest. Not that they shouldn't be used, but using fixtures is better suited. The documentation details the benefits of using fixtures. There’s also a note at the top of this page on xunitsetup encouraging to use fixtures.
Why do you want to re-create
dtype
andx
?
If a test modifies dtype
and/or x
, then it will affect all the other tests which violates the principle that tests should be independent and without side effects on the other tests. By ensuring that each test gets a properly initialized x
and dtype
, we prevent such situation. However, we could remove the delattr
calls (and drop the yield
) because x
and dtype
will be overwritten in the next test anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case then I think it would be clearer if x
was passed in to the tests that need it as an additional argument, rather than stuffing it onto self
. Tests that need dtype
should just call x.dtype
. As I commented elsewhere, this use/abuse of self.x
seems weird.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I refactored TestIO
to use a fixture (x
) and also updated all the self.filename
references to use the value from the tmp_filename
fixture instead, which remove all attributes stored in self
.
Is it too much out of scope to refactor TestMemmap
to use fixtures too since the original issue was to remove the deprecated mktemp()
function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the TestMemmap
is fine as is. I would like to keep the use of fixtures to a minimum, it adds a layer of indirection that is harder to parse.
16bd061
to
5a7ab10
Compare
numpy/core/tests/test_multiarray.py
Outdated
else: | ||
yield | ||
|
||
def test_nan(self, tmp_filename, comma_decimal_point_locale): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not clear form the code how comma_decimal_point_locale is ever used. A comment would be helpful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just to be clear: the previous code was also opaque as to what this does
Thanks, I think this is a big improvement. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, besides one nit for a comment. Would anyone else like to take a look?
Co-authored-by: alize-papp <68250865+alize-papp@users.noreply.github.com>
Co-authored-by: alize-papp <68250865+alize-papp@users.noreply.github.com>
- `test_roundtrip_filename` and `test_roundtrip_pathlib` are now combined into a single test. The fixture covers both the filename as a string and a pathlib object - Added fixture for testing localized decimal point to replace `test_locale`
- Removed `x`, `dtype`, and `filename` from class attributes
- Renamed `comma_decimal_point_locale` to `decimal_sep_localization` - Added a docstring explaining its usage
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM as well - using pytest features for the tmp file handling is a nice improvement IMO. Thanks @lyzlisa !
Closes #12071
mktemp
tomkstemp
sincemktemp
was deprecatednumpy/lib/tests/test_format.py