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] Catch missed test warnings, clean up validation warnings with DSdecimal #2107

Merged
merged 2 commits into from
Jul 21, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Cleanup test warnings
  • Loading branch information
scaramallion committed Jul 20, 2024
commit 6ff4ebbbb6384b3d251eee6beed8e4f1e3123b31
5 changes: 0 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,3 @@ We are all volunteers working on *pydicom* in our free time. As our
resources are limited, we very much value your contributions, be it bug fixes, new
core features, or documentation improvements. For more information, please
read our [contribution guide](https://github.com/pydicom/pydicom/blob/main/CONTRIBUTING.md).

If you have examples or extensions of *pydicom* that don't belong with the
core software, but that you deem useful to others, you can add them to our
contribution repository:
[contrib-pydicom](https://www.github.com/pydicom/contrib-pydicom).
7 changes: 4 additions & 3 deletions src/pydicom/valuerep.py
Original file line number Diff line number Diff line change
Expand Up @@ -1108,7 +1108,7 @@ def __str__(self) -> str:
return repr(self)[1:-1]

def __repr__(self) -> str:
if self.auto_format and hasattr(self, "original_string"):
Copy link
Member

Choose a reason for hiding this comment

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

I actually don't understand in what situations autoformat is needed.

Copy link
Member Author

Choose a reason for hiding this comment

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

It's a bit of an odd thing, you'd only be able to use it if creating your own values, in which case you'd presumably just format them correctly beforehand?

Copy link
Member

Choose a reason for hiding this comment

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

Yes, that's what I've thought, too... Maybe @darcymason knows more?

Copy link
Member

Choose a reason for hiding this comment

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

It came from #1264/#1334, just a shorthand way to allow users to fix DS problems automatically.

if hasattr(self, "original_string"):
return f"'{self.original_string}'"

return f"'{super().__repr__()}'"
Expand Down Expand Up @@ -1219,7 +1219,7 @@ def __init__(
if validation_mode == config.RAISE:
raise OverflowError(msg)
warn_and_log(msg)
if not is_valid_ds(repr(self).strip("'")):
elif not is_valid_ds(repr(self).strip("'")):
# This will catch nan and inf
msg = f'Value "{self}" is not valid for elements with a VR of DS'
if validation_mode == config.RAISE:
Expand Down Expand Up @@ -1247,8 +1247,9 @@ def __str__(self) -> str:
return super().__str__()

def __repr__(self) -> str:
if self.auto_format and hasattr(self, "original_string"):
if hasattr(self, "original_string"):
return f"'{self.original_string}'"

return f"'{self}'"


Expand Down
4 changes: 2 additions & 2 deletions tests/pixels/test_processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -1819,9 +1819,9 @@ def test_sequence_8bit_unsigned(self):
# 4096 entries, 8-bit output, LUTData as 16-bit bytes
seq[0].LUTDescriptor = [4096, 0, 16]
seq[0]["LUTData"].VR = "OW"
seq[0].LUTData = [int(round(x * (2**16 - 1) / 4095, 0)) for x in range(0, 4096)]
data = [int(round(x * (2**16 - 1) / 4095, 0)) for x in range(0, 4096)]
seq[0].LUTData = b"".join(
x.to_bytes(length=2, byteorder="little") for x in seq[0].LUTData
x.to_bytes(length=2, byteorder="little") for x in data
)
out = apply_presentation_lut(arr, ds)
results = [
Expand Down
16 changes: 8 additions & 8 deletions tests/test_charset.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,14 +205,14 @@ def test_code_extensions_not_allowed(self):

def test_convert_encodings_warnings(self):
"""Test warning if stand-alone encodings are used as code extension"""
with pytest.warns(
UserWarning,
match="Value 'GBK' cannot be used as code extension, ignoring it",
):
encodings = pydicom.charset.convert_encodings(
["ISO_IR 126", "GBK", "ISO 2022 IR 144", "ISO_IR 192"]
)
assert ["iso_ir_126", "iso_ir_144"] == encodings
msg_iso = "Value 'ISO_IR 192' cannot be used as code extension, ignoring it"
msg_gbk = "Value 'GBK' cannot be used as code extension, ignoring it"
with pytest.warns(UserWarning, match=msg_iso):
with pytest.warns(UserWarning, match=msg_gbk):
encodings = pydicom.charset.convert_encodings(
["ISO_IR 126", "GBK", "ISO 2022 IR 144", "ISO_IR 192"]
)
assert ["iso_ir_126", "iso_ir_144"] == encodings

def test_convert_python_encodings(self):
"""Test that unknown encodings are returned unchanged by
Expand Down
26 changes: 8 additions & 18 deletions tests/test_filewriter.py
Original file line number Diff line number Diff line change
Expand Up @@ -3244,33 +3244,23 @@ def test_writing_dataset_with_buffered_pixel_data(self, bits_allocated):
def test_writing_dataset_with_buffered_pixel_data_reads_data_in_chunks(
self, bits_allocated
):
FILE_SIZE = 100 # MB
KILOBYTE = 1000
MEGABYTE = KILOBYTE * 1000
bytes_per_iter = MEGABYTE
FILE_SIZE = 50 * MEGABYTE

ds = Dataset()
ds.BitsAllocated = bits_allocated

with TemporaryFile("+wb") as large_dataset, TemporaryFile("+wb") as fp:
# generate large file
data = BytesIO()
for _ in range(bytes_per_iter):
data.write(b"\x00")

data.seek(0)

# 500 megabytes
for _ in range(FILE_SIZE):
large_dataset.write(data.getbuffer())

large_dataset.seek(0)
with TemporaryFile("+wb") as buffer, TemporaryFile("+wb") as fp:
# 100 megabytes
buffer.write(b"\x00" * FILE_SIZE)
buffer.seek(0)

# take a snapshot of memory
baseline_memory_usage = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss

# set the pixel data to the buffer
ds.PixelData = large_dataset
ds.PixelData = buffer
ds.save_as(fp, little_endian=True, implicit_vr=False)

memory_usage = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
Expand All @@ -3279,10 +3269,10 @@ def test_writing_dataset_with_buffered_pixel_data_reads_data_in_chunks(
limit = 0
if sys.platform.startswith("linux"):
# memory usage is in kilobytes
limit = (MEGABYTE * FILE_SIZE / 5 * 4) / KILOBYTE
limit = (FILE_SIZE / 5 * 4) / KILOBYTE
elif sys.platform.startswith("darwin"):
# memory usage is in bytes
limit = MEGABYTE * FILE_SIZE / 5 * 4
limit = FILE_SIZE / 5 * 4
else:
pytest.skip("This test is not setup to run on this platform")

Expand Down
2 changes: 1 addition & 1 deletion tests/test_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def test_code_dataelem_standard(self):
def test_code_dataelem_exclude_size(self):
"""Test utils.codify.code_dataelem exclude_size param"""
input_elem = [
DataElement(0x00100010, "OB", "CITIZEN"),
DataElement(0x00100010, "OB", b"CITIZEN"),
DataElement(0x0008010C, "UI", "1.1"),
DataElement(0x00200011, "IS", 3),
]
Expand Down
25 changes: 21 additions & 4 deletions tests/test_valuerep.py
Original file line number Diff line number Diff line change
Expand Up @@ -745,7 +745,17 @@ def test_DSfloat(self):
def test_DSdecimal(self, allow_ds_float):
"""Test creating a value using DSdecimal."""
x = DSfloat("1.2345")
assert x.original_string == "1.2345"
assert not x.auto_format
assert str(x) == "1.2345"
assert repr(x) == "'1.2345'"

y = DSdecimal(x)
assert y.original_string == "1.2345"
assert not y.auto_format
assert str(y) == "1.2345"
assert repr(y) == "'1.2345'"

assert Decimal(1.2345) == y
assert "1.2345" == y.original_string

Expand Down Expand Up @@ -915,15 +925,22 @@ def test_float_value(self):
bin_elem = b"\x18\x00\x52\x11\x04\x00\x00\x0014.5"
with BytesIO(bin_elem) as bio:
ds = read_dataset(bio, True, True)
with pytest.warns(UserWarning, match="Invalid value for VR IS"):
assert isinstance(ds.Exposure, ISfloat)

# Will warn when the element is first converted to DataElement
msg1 = 'Value "14.5" is not valid for elements with a VR of IS'
msg2 = "Invalid value for VR IS: '14.5'"
with pytest.warns(UserWarning, match=msg1):
with pytest.warns(UserWarning, match=msg2):
assert isinstance(ds.Exposure, ISfloat)

assert ds.Exposure == 14.5

# Strict checking raises an error
with pytest.raises(ValueError):
_ = IS("14.5", validation_mode=config.RAISE)
IS("14.5", validation_mode=config.RAISE)

with pytest.raises(TypeError):
_ = IS(14.5, validation_mode=config.RAISE)
IS(14.5, validation_mode=config.RAISE)

def test_float_init(self):
"""New ISfloat created from another behaves correctly"""
Expand Down
Loading