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

PyPI #9

Open
jayvdb opened this issue Sep 24, 2022 · 15 comments
Open

PyPI #9

jayvdb opened this issue Sep 24, 2022 · 15 comments

Comments

@jayvdb
Copy link

jayvdb commented Sep 24, 2022

In order to assist with building distro packages, such as https://build.opensuse.org/package/show/devel:languages:python/python-pydicom and the other distros listed at https://repology.org/project/python:pydicom/versions , it would be very helpful if this data was packaged onto PyPI and was versioned.

A similar case is https://github.com/pythongssapi/k5test which is only needed for testing, and is available at https://pypi.org/project/k5test/ , and distros use that versioned package for testing only. c.f. https://repology.org/project/python:k5test/versions

@darcymason
Copy link
Member

Sure, I see no reason why we can't do this. I can look into it in the next few days or so.

@darcymason
Copy link
Member

So I looked into this - there was already a setup.py in place, so I just did the wheel build and uploaded to Test PyPI with the existing 1.0.0.dev0 version number.

Do you want to try it from there first? Or I can jump to putting a 1.0.0 together and uploading to normal PyPI.

On reviewing how all this was set up, I will note here for myself and others the reminder that the pydicom data store does not need this repo at all (it will fetch any test files accessed as needed), but if the repo is available locally it will access that local copy via pydicom-data entry points that pydicom calls.

@jayvdb
Copy link
Author

jayvdb commented Sep 27, 2022

For distro packaging purposes, a tarball - the sdist - is the preferred format.

But I have set up the whl as a package, and run the pydicom tests.

First problem is pydicom/pydicom#1697

I'll keep going with this, and report other issues I encounter.

@jayvdb
Copy link
Author

jayvdb commented Sep 27, 2022

Ok having this on PyPI is a huge improvement. It would be really helpful if this could be promoted to pypi.org, and an sdist uploaded.

Now my pydicom test script is below, and at https://build.opensuse.org/package/show/home:jayvdb:branches:devel:languages:python/python-pydicom
(it was much worse..)

export LANG=en_US.UTF-8

# Needs network
skips="test_fetch_data_files"

# Failures only on ppc64
skips="$skips or test_invalid_arr_dtype_raises or TestHandlerGenerateMultiplex or TestHandlerMultiplexArray or TestNumpy_PaletteColor"
skips="$skips or (TestNumpy_NumpyHandler and (test_properties or test_little_16bit_1sample_1frame_padded or test_endianness_not_set))"
skips="$skips or (TestNumpy_GetPixelData and (test_float_pixel_data or test_double_float_pixel_data))"
skips="$skips or (TestPillowHandler_JPEG2K and test_properties) or test_encoders_gdcm"
skips="$skips or (test_gdcm_pixel_data.py and TestsWithGDCM)"
skips="$skips or (Test_JPEG_LS_Lossless_transfer_syntax and (test_read_mr_with_gdcm or test_read_emri_with_gdcm))"

# Failures only on i586
skips="$skips or test_write_file_id or test_file_id or test_encapsulate_bot_large_raises or (TestPillowHandler_JPEG2K and test_array)"

# These ignores cause failure during test collection
# https://github.com/pydicom/pydicom/issues/1697
ignores="--ignore pydicom/tests/test_dataset.py --ignore pydicom/tests/test_data_manager.py"

%{pytest -rs pydicom/tests $ignores -k "not ($skips)"

@darcymason
Copy link
Member

I've uploaded the sdist to test PyPI. I'd like to update to a proper version number before uploading to regular PyPI, hopefully tomorrow.

@darcymason
Copy link
Member

Sorry for the delay. A 1.0.0 version of pydicom-data has now been uploaded to PyPI.

@jayvdb
Copy link
Author

jayvdb commented Oct 9, 2022

Hmm, I now have four failures

[   74s] _ TestNumpy_NumpyHandler.test_big_endian_datasets[/usr/lib/python3.8/site-packages/data_store/data/OBXXXX1A.dcm-None] _
[   74s] 
[   74s] self = <pydicom.tests.test_numpy_pixel_data.TestNumpy_NumpyHandler object at 0x7f19631e66d0>
[   74s] little = '/usr/lib/python3.8/site-packages/data_store/data/OBXXXX1A.dcm'
[   74s] big = None
[   74s] 
[   74s]     @pytest.mark.parametrize('little, big', MATCHING_DATASETS)
[   74s]     def test_big_endian_datasets(self, little, big):
[   74s]         """Test pixel_array for big endian matches little."""
[   74s] >       ds = dcmread(big)
[   74s] 
[   74s] pydicom/tests/test_numpy_pixel_data.py:1058: 
[   74s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[   74s] 
[   74s] fp = None, defer_size = None, stop_before_pixels = False, force = False
[   74s] specific_tags = None
[   74s] 
[   74s]     def dcmread(
[   74s]         fp: Union[PathType, BinaryIO, DicomFileLike],
[   74s]         defer_size: Optional[Union[str, int, float]] = None,
[   74s]         stop_before_pixels: bool = False,
[   74s]         force: bool = False,
[   74s]         specific_tags: Optional[TagListType] = None
[   74s]     ) -> Union[FileDataset, DicomDir]:
[   74s]         """Read and parse a DICOM dataset stored in the DICOM File Format.
[   74s]     
[   74s]         Read a DICOM dataset stored in accordance with the :dcm:`DICOM File
[   74s]         Format <part10/chapter_7.html>`. If the dataset is not stored in
[   74s]         accordance with the File Format (i.e. the preamble and prefix are missing,
[   74s]         there are missing required Type 1 *File Meta Information Group* elements
[   74s]         or the entire *File Meta Information* is missing) then you will have to
[   74s]         set `force` to ``True``.
[   74s]     
[   74s]         .. deprecated:: 2.2
[   74s]     
[   74s]             Returning a :class:`~pydicom.dicomdir.DicomDir` is deprecated and
[   74s]             will be removed in v3.0. Use :class:`~pydicom.fileset.FileSet` instead.
[   74s]     
[   74s]     
[   74s]         Examples
[   74s]         --------
[   74s]         Read and return a dataset stored in accordance with the DICOM File Format:
[   74s]     
[   74s]         >>> ds = pydicom.dcmread("CT_small.dcm")
[   74s]         >>> ds.PatientName
[   74s]     
[   74s]         Read and return a dataset not in accordance with the DICOM File Format:
[   74s]     
[   74s]         >>> ds = pydicom.dcmread("rtplan.dcm", force=True)
[   74s]         >>> ds.PatientName
[   74s]     
[   74s]         Use within a context manager:
[   74s]     
[   74s]         >>> with pydicom.dcmread("rtplan.dcm") as ds:
[   74s]         ...     ds.PatientName
[   74s]     
[   74s]         Parameters
[   74s]         ----------
[   74s]         fp : str or PathLike or file-like
[   74s]             Either a file-like object, a string containing the file name or the
[   74s]             path to the file. The file-like object must have ``seek()``,
[   74s]             ``read()`` and ``tell()`` methods and the caller is responsible for
[   74s]             closing it (if required).
[   74s]         defer_size : int, str or float, optional
[   74s]             If not used then all elements are read into memory. If specified,
[   74s]             then if a data element's stored value is larger than `defer_size`, the
[   74s]             value is not read into memory until it is accessed in code. Should be
[   74s]             the number of bytes to be read as :class:`int` or as a :class:`str`
[   74s]             with units, e.g. ``'512 KB'``, ``'2 MB'``.
[   74s]         stop_before_pixels : bool, optional
[   74s]             If ``False`` (default), the full file will be read and parsed. Set
[   74s]             ``True`` to stop before reading (7FE0,0010) *Pixel Data* (and all
[   74s]             subsequent elements).
[   74s]         force : bool, optional
[   74s]             If ``False`` (default), raises an
[   74s]             :class:`~pydicom.errors.InvalidDicomError` if the file is
[   74s]             missing the *File Meta Information* header. Set to ``True`` to force
[   74s]             reading even if no *File Meta Information* header is found.
[   74s]         specific_tags : list of (int or str or 2-tuple of int), optional
[   74s]             If used the only the supplied tags will be returned. The supplied
[   74s]             elements can be tags or keywords. Note that the element (0008,0005)
[   74s]             *Specific Character Set* is always returned if present - this ensures
[   74s]             correct decoding of returned text values.
[   74s]     
[   74s]         Returns
[   74s]         -------
[   74s]         FileDataset or DicomDir
[   74s]             An instance of :class:`~pydicom.dataset.FileDataset` that represents
[   74s]             a parsed DICOM file, unless the dataset is a *Media Storage Directory*
[   74s]             instance in which case it will be a
[   74s]             :class:`~pydicom.dicomdir.DicomDir`.
[   74s]     
[   74s]         Raises
[   74s]         ------
[   74s]         InvalidDicomError
[   74s]             If `force` is ``False`` and the file is not a valid DICOM file.
[   74s]         TypeError
[   74s]             If `fp` is ``None`` or of an unsupported type.
[   74s]     
[   74s]         See Also
[   74s]         --------
[   74s]         pydicom.dataset.FileDataset
[   74s]             Data class that is returned.
[   74s]         pydicom.filereader.read_partial
[   74s]             Only read part of a DICOM file, stopping on given conditions.
[   74s]         """
[   74s]         # Open file if not already a file object
[   74s]         caller_owns_file = True
[   74s]         fp = path_from_pathlike(fp)
[   74s]         if isinstance(fp, str):
[   74s]             # caller provided a file name; we own the file handle
[   74s]             caller_owns_file = False
[   74s]             logger.debug("Reading file '{0}'".format(fp))
[   74s]             fp = open(fp, 'rb')
[   74s]         elif fp is None or not hasattr(fp, "read") or not hasattr(fp, "seek"):
[   74s] >           raise TypeError("dcmread: Expected a file path or a file-like, "
[   74s]                             "but got " + type(fp).__name__)
[   74s] E           TypeError: dcmread: Expected a file path or a file-like, but got NoneType
[   74s] 
[   74s] pydicom/filereader.py:995: TypeError
[   74s] _ TestNumpy_NumpyHandler.test_big_endian_datasets[/usr/lib/python3.8/site-packages/data_store/data/OBXXXX1A_2frame.dcm-None] _
[   74s] 
[   74s] self = <pydicom.tests.test_numpy_pixel_data.TestNumpy_NumpyHandler object at 0x7f19631e6490>
[   74s] little = '/usr/lib/python3.8/site-packages/data_store/data/OBXXXX1A_2frame.dcm'
[   74s] big = None
[   74s] 
[   74s]     @pytest.mark.parametrize('little, big', MATCHING_DATASETS)
[   74s]     def test_big_endian_datasets(self, little, big):
[   74s]         """Test pixel_array for big endian matches little."""
[   74s] >       ds = dcmread(big)
[   74s] 
[   74s] pydicom/tests/test_numpy_pixel_data.py:1058: 
[   74s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[   74s] 
[   74s] fp = None, defer_size = None, stop_before_pixels = False, force = False
[   74s] specific_tags = None
[   74s] 
[   74s]     def dcmread(
[   74s]         fp: Union[PathType, BinaryIO, DicomFileLike],
[   74s]         defer_size: Optional[Union[str, int, float]] = None,
[   74s]         stop_before_pixels: bool = False,
[   74s]         force: bool = False,
[   74s]         specific_tags: Optional[TagListType] = None
[   74s]     ) -> Union[FileDataset, DicomDir]:
[   74s]         """Read and parse a DICOM dataset stored in the DICOM File Format.
[   74s]     
[   74s]         Read a DICOM dataset stored in accordance with the :dcm:`DICOM File
[   74s]         Format <part10/chapter_7.html>`. If the dataset is not stored in
[   74s]         accordance with the File Format (i.e. the preamble and prefix are missing,
[   74s]         there are missing required Type 1 *File Meta Information Group* elements
[   74s]         or the entire *File Meta Information* is missing) then you will have to
[   74s]         set `force` to ``True``.
[   74s]     
[   74s]         .. deprecated:: 2.2
[   74s]     
[   74s]             Returning a :class:`~pydicom.dicomdir.DicomDir` is deprecated and
[   74s]             will be removed in v3.0. Use :class:`~pydicom.fileset.FileSet` instead.
[   74s]     
[   74s]     
[   74s]         Examples
[   74s]         --------
[   74s]         Read and return a dataset stored in accordance with the DICOM File Format:
[   74s]     
[   74s]         >>> ds = pydicom.dcmread("CT_small.dcm")
[   74s]         >>> ds.PatientName
[   74s]     
[   74s]         Read and return a dataset not in accordance with the DICOM File Format:
[   74s]     
[   74s]         >>> ds = pydicom.dcmread("rtplan.dcm", force=True)
[   74s]         >>> ds.PatientName
[   74s]     
[   74s]         Use within a context manager:
[   74s]     
[   74s]         >>> with pydicom.dcmread("rtplan.dcm") as ds:
[   74s]         ...     ds.PatientName
[   74s]     
[   74s]         Parameters
[   74s]         ----------
[   74s]         fp : str or PathLike or file-like
[   74s]             Either a file-like object, a string containing the file name or the
[   74s]             path to the file. The file-like object must have ``seek()``,
[   74s]             ``read()`` and ``tell()`` methods and the caller is responsible for
[   74s]             closing it (if required).
[   74s]         defer_size : int, str or float, optional
[   74s]             If not used then all elements are read into memory. If specified,
[   74s]             then if a data element's stored value is larger than `defer_size`, the
[   74s]             value is not read into memory until it is accessed in code. Should be
[   74s]             the number of bytes to be read as :class:`int` or as a :class:`str`
[   74s]             with units, e.g. ``'512 KB'``, ``'2 MB'``.
[   74s]         stop_before_pixels : bool, optional
[   74s]             If ``False`` (default), the full file will be read and parsed. Set
[   74s]             ``True`` to stop before reading (7FE0,0010) *Pixel Data* (and all
[   74s]             subsequent elements).
[   74s]         force : bool, optional
[   74s]             If ``False`` (default), raises an
[   74s]             :class:`~pydicom.errors.InvalidDicomError` if the file is
[   74s]             missing the *File Meta Information* header. Set to ``True`` to force
[   74s]             reading even if no *File Meta Information* header is found.
[   74s]         specific_tags : list of (int or str or 2-tuple of int), optional
[   74s]             If used the only the supplied tags will be returned. The supplied
[   74s]             elements can be tags or keywords. Note that the element (0008,0005)
[   74s]             *Specific Character Set* is always returned if present - this ensures
[   74s]             correct decoding of returned text values.
[   74s]     
[   74s]         Returns
[   74s]         -------
[   74s]         FileDataset or DicomDir
[   74s]             An instance of :class:`~pydicom.dataset.FileDataset` that represents
[   74s]             a parsed DICOM file, unless the dataset is a *Media Storage Directory*
[   74s]             instance in which case it will be a
[   74s]             :class:`~pydicom.dicomdir.DicomDir`.
[   74s]     
[   74s]         Raises
[   74s]         ------
[   74s]         InvalidDicomError
[   74s]             If `force` is ``False`` and the file is not a valid DICOM file.
[   74s]         TypeError
[   74s]             If `fp` is ``None`` or of an unsupported type.
[   74s]     
[   74s]         See Also
[   74s]         --------
[   74s]         pydicom.dataset.FileDataset
[   74s]             Data class that is returned.
[   74s]         pydicom.filereader.read_partial
[   74s]             Only read part of a DICOM file, stopping on given conditions.
[   74s]         """
[   74s]         # Open file if not already a file object
[   74s]         caller_owns_file = True
[   74s]         fp = path_from_pathlike(fp)
[   74s]         if isinstance(fp, str):
[   74s]             # caller provided a file name; we own the file handle
[   74s]             caller_owns_file = False
[   74s]             logger.debug("Reading file '{0}'".format(fp))
[   74s]             fp = open(fp, 'rb')
[   74s]         elif fp is None or not hasattr(fp, "read") or not hasattr(fp, "seek"):
[   74s] >           raise TypeError("dcmread: Expected a file path or a file-like, "
[   74s]                             "but got " + type(fp).__name__)
[   74s] E           TypeError: dcmread: Expected a file path or a file-like, but got NoneType
[   74s] 
[   74s] pydicom/filereader.py:995: TypeError
[   74s] ___ TestPillowHandler_JPEG2K.test_can_access_unsupported_dataset[None-data2] ___
[   74s] 
[   74s] self = <pydicom.tests.test_pillow_pixel_data.TestPillowHandler_JPEG2K object at 0x7f1962eb17c0>
[   74s] fpath = None, data = ('1.2.840.10008.1.2.2', 'OB^^^^')
[   74s] 
[   74s]     @pytest.mark.parametrize("fpath, data", REFERENCE_DATA_UNSUPPORTED)
[   74s]     def test_can_access_unsupported_dataset(self, fpath, data):
[   74s]         """Test can read and access elements in unsupported datasets."""
[   74s] >       ds = dcmread(fpath)
[   74s] 
[   74s] pydicom/tests/test_pillow_pixel_data.py:414: 
[   74s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[   74s] 
[   74s] fp = None, defer_size = None, stop_before_pixels = False, force = False
[   74s] specific_tags = None
[   74s] 
[   74s]     def dcmread(
[   74s]         fp: Union[PathType, BinaryIO, DicomFileLike],
[   74s]         defer_size: Optional[Union[str, int, float]] = None,
[   74s]         stop_before_pixels: bool = False,
[   74s]         force: bool = False,
[   74s]         specific_tags: Optional[TagListType] = None
[   74s]     ) -> Union[FileDataset, DicomDir]:
[   74s]         """Read and parse a DICOM dataset stored in the DICOM File Format.
[   74s]     
[   74s]         Read a DICOM dataset stored in accordance with the :dcm:`DICOM File
[   74s]         Format <part10/chapter_7.html>`. If the dataset is not stored in
[   74s]         accordance with the File Format (i.e. the preamble and prefix are missing,
[   74s]         there are missing required Type 1 *File Meta Information Group* elements
[   74s]         or the entire *File Meta Information* is missing) then you will have to
[   74s]         set `force` to ``True``.
[   74s]     
[   74s]         .. deprecated:: 2.2
[   74s]     
[   74s]             Returning a :class:`~pydicom.dicomdir.DicomDir` is deprecated and
[   74s]             will be removed in v3.0. Use :class:`~pydicom.fileset.FileSet` instead.
[   74s]     
[   74s]     
[   74s]         Examples
[   74s]         --------
[   74s]         Read and return a dataset stored in accordance with the DICOM File Format:
[   74s]     
[   74s]         >>> ds = pydicom.dcmread("CT_small.dcm")
[   74s]         >>> ds.PatientName
[   74s]     
[   74s]         Read and return a dataset not in accordance with the DICOM File Format:
[   74s]     
[   74s]         >>> ds = pydicom.dcmread("rtplan.dcm", force=True)
[   74s]         >>> ds.PatientName
[   74s]     
[   74s]         Use within a context manager:
[   74s]     
[   74s]         >>> with pydicom.dcmread("rtplan.dcm") as ds:
[   74s]         ...     ds.PatientName
[   74s]     
[   74s]         Parameters
[   74s]         ----------
[   74s]         fp : str or PathLike or file-like
[   74s]             Either a file-like object, a string containing the file name or the
[   74s]             path to the file. The file-like object must have ``seek()``,
[   74s]             ``read()`` and ``tell()`` methods and the caller is responsible for
[   74s]             closing it (if required).
[   74s]         defer_size : int, str or float, optional
[   74s]             If not used then all elements are read into memory. If specified,
[   74s]             then if a data element's stored value is larger than `defer_size`, the
[   74s]             value is not read into memory until it is accessed in code. Should be
[   74s]             the number of bytes to be read as :class:`int` or as a :class:`str`
[   74s]             with units, e.g. ``'512 KB'``, ``'2 MB'``.
[   74s]         stop_before_pixels : bool, optional
[   74s]             If ``False`` (default), the full file will be read and parsed. Set
[   74s]             ``True`` to stop before reading (7FE0,0010) *Pixel Data* (and all
[   74s]             subsequent elements).
[   74s]         force : bool, optional
[   74s]             If ``False`` (default), raises an
[   74s]             :class:`~pydicom.errors.InvalidDicomError` if the file is
[   74s]             missing the *File Meta Information* header. Set to ``True`` to force
[   74s]             reading even if no *File Meta Information* header is found.
[   74s]         specific_tags : list of (int or str or 2-tuple of int), optional
[   74s]             If used the only the supplied tags will be returned. The supplied
[   74s]             elements can be tags or keywords. Note that the element (0008,0005)
[   74s]             *Specific Character Set* is always returned if present - this ensures
[   74s]             correct decoding of returned text values.
[   74s]     
[   74s]         Returns
[   74s]         -------
[   74s]         FileDataset or DicomDir
[   74s]             An instance of :class:`~pydicom.dataset.FileDataset` that represents
[   74s]             a parsed DICOM file, unless the dataset is a *Media Storage Directory*
[   74s]             instance in which case it will be a
[   74s]             :class:`~pydicom.dicomdir.DicomDir`.
[   74s]     
[   74s]         Raises
[   74s]         ------
[   74s]         InvalidDicomError
[   74s]             If `force` is ``False`` and the file is not a valid DICOM file.
[   74s]         TypeError
[   74s]             If `fp` is ``None`` or of an unsupported type.
[   74s]     
[   74s]         See Also
[   74s]         --------
[   74s]         pydicom.dataset.FileDataset
[   74s]             Data class that is returned.
[   74s]         pydicom.filereader.read_partial
[   74s]             Only read part of a DICOM file, stopping on given conditions.
[   74s]         """
[   74s]         # Open file if not already a file object
[   74s]         caller_owns_file = True
[   74s]         fp = path_from_pathlike(fp)
[   74s]         if isinstance(fp, str):
[   74s]             # caller provided a file name; we own the file handle
[   74s]             caller_owns_file = False
[   74s]             logger.debug("Reading file '{0}'".format(fp))
[   74s]             fp = open(fp, 'rb')
[   74s]         elif fp is None or not hasattr(fp, "read") or not hasattr(fp, "seek"):
[   74s] >           raise TypeError("dcmread: Expected a file path or a file-like, "
[   74s]                             "but got " + type(fp).__name__)
[   74s] E           TypeError: dcmread: Expected a file path or a file-like, but got NoneType
[   74s] 
[   74s] pydicom/filereader.py:995: TypeError
[   74s] ____ TestPillowHandler_JPEG.test_can_access_unsupported_dataset[None-data2] ____
[   74s] 
[   74s] self = <pydicom.tests.test_pillow_pixel_data.TestPillowHandler_JPEG object at 0x7f1962e85f70>
[   74s] fpath = None, data = ('1.2.840.10008.1.2.2', 'OB^^^^')
[   74s] 
[   74s]     @pytest.mark.parametrize("fpath, data", REFERENCE_DATA_UNSUPPORTED)
[   74s]     def test_can_access_unsupported_dataset(self, fpath, data):
[   74s]         """Test can read and access elements in unsupported datasets."""
[   74s] >       ds = dcmread(fpath)
[   74s] 
[   74s] pydicom/tests/test_pillow_pixel_data.py:545: 
[   74s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[   74s] 
[   74s] fp = None, defer_size = None, stop_before_pixels = False, force = False
[   74s] specific_tags = None
[   74s] 
[   74s]     def dcmread(
[   74s]         fp: Union[PathType, BinaryIO, DicomFileLike],
[   74s]         defer_size: Optional[Union[str, int, float]] = None,
[   74s]         stop_before_pixels: bool = False,
[   74s]         force: bool = False,
[   74s]         specific_tags: Optional[TagListType] = None
[   74s]     ) -> Union[FileDataset, DicomDir]:
[   74s]         """Read and parse a DICOM dataset stored in the DICOM File Format.
[   74s]     
[   74s]         Read a DICOM dataset stored in accordance with the :dcm:`DICOM File
[   74s]         Format <part10/chapter_7.html>`. If the dataset is not stored in
[   74s]         accordance with the File Format (i.e. the preamble and prefix are missing,
[   74s]         there are missing required Type 1 *File Meta Information Group* elements
[   74s]         or the entire *File Meta Information* is missing) then you will have to
[   74s]         set `force` to ``True``.
[   74s]     
[   74s]         .. deprecated:: 2.2
[   74s]     
[   74s]             Returning a :class:`~pydicom.dicomdir.DicomDir` is deprecated and
[   74s]             will be removed in v3.0. Use :class:`~pydicom.fileset.FileSet` instead.
[   74s]     
[   74s]     
[   74s]         Examples
[   74s]         --------
[   74s]         Read and return a dataset stored in accordance with the DICOM File Format:
[   74s]     
[   74s]         >>> ds = pydicom.dcmread("CT_small.dcm")
[   74s]         >>> ds.PatientName
[   74s]     
[   74s]         Read and return a dataset not in accordance with the DICOM File Format:
[   74s]     
[   74s]         >>> ds = pydicom.dcmread("rtplan.dcm", force=True)
[   74s]         >>> ds.PatientName
[   74s]     
[   74s]         Use within a context manager:
[   74s]     
[   74s]         >>> with pydicom.dcmread("rtplan.dcm") as ds:
[   74s]         ...     ds.PatientName
[   74s]     
[   74s]         Parameters
[   74s]         ----------
[   74s]         fp : str or PathLike or file-like
[   74s]             Either a file-like object, a string containing the file name or the
[   74s]             path to the file. The file-like object must have ``seek()``,
[   74s]             ``read()`` and ``tell()`` methods and the caller is responsible for
[   74s]             closing it (if required).
[   74s]         defer_size : int, str or float, optional
[   74s]             If not used then all elements are read into memory. If specified,
[   74s]             then if a data element's stored value is larger than `defer_size`, the
[   74s]             value is not read into memory until it is accessed in code. Should be
[   74s]             the number of bytes to be read as :class:`int` or as a :class:`str`
[   74s]             with units, e.g. ``'512 KB'``, ``'2 MB'``.
[   74s]         stop_before_pixels : bool, optional
[   74s]             If ``False`` (default), the full file will be read and parsed. Set
[   74s]             ``True`` to stop before reading (7FE0,0010) *Pixel Data* (and all
[   74s]             subsequent elements).
[   74s]         force : bool, optional
[   74s]             If ``False`` (default), raises an
[   74s]             :class:`~pydicom.errors.InvalidDicomError` if the file is
[   74s]             missing the *File Meta Information* header. Set to ``True`` to force
[   74s]             reading even if no *File Meta Information* header is found.
[   74s]         specific_tags : list of (int or str or 2-tuple of int), optional
[   74s]             If used the only the supplied tags will be returned. The supplied
[   74s]             elements can be tags or keywords. Note that the element (0008,0005)
[   74s]             *Specific Character Set* is always returned if present - this ensures
[   74s]             correct decoding of returned text values.
[   74s]     
[   74s]         Returns
[   74s]         -------
[   74s]         FileDataset or DicomDir
[   74s]             An instance of :class:`~pydicom.dataset.FileDataset` that represents
[   74s]             a parsed DICOM file, unless the dataset is a *Media Storage Directory*
[   74s]             instance in which case it will be a
[   74s]             :class:`~pydicom.dicomdir.DicomDir`.
[   74s]     
[   74s]         Raises
[   74s]         ------
[   74s]         InvalidDicomError
[   74s]             If `force` is ``False`` and the file is not a valid DICOM file.
[   74s]         TypeError
[   74s]             If `fp` is ``None`` or of an unsupported type.
[   74s]     
[   74s]         See Also
[   74s]         --------
[   74s]         pydicom.dataset.FileDataset
[   74s]             Data class that is returned.
[   74s]         pydicom.filereader.read_partial
[   74s]             Only read part of a DICOM file, stopping on given conditions.
[   74s]         """
[   74s]         # Open file if not already a file object
[   74s]         caller_owns_file = True
[   74s]         fp = path_from_pathlike(fp)
[   74s]         if isinstance(fp, str):
[   74s]             # caller provided a file name; we own the file handle
[   74s]             caller_owns_file = False
[   74s]             logger.debug("Reading file '{0}'".format(fp))
[   74s]             fp = open(fp, 'rb')
[   74s]         elif fp is None or not hasattr(fp, "read") or not hasattr(fp, "seek"):
[   74s] >           raise TypeError("dcmread: Expected a file path or a file-like, "
[   74s]                             "but got " + type(fp).__name__)
[   74s] E           TypeError: dcmread: Expected a file path or a file-like, but got NoneType
[   74s] 
[   74s] pydicom/filereader.py:995: TypeError
[   74s] =============================== warnings summary ===============================
[   74s] pydicom/data/data_manager.py:365
[   74s]   /home/abuild/rpmbuild/BUILD/pydicom-2.3.0/pydicom/data/data_manager.py:365: UserWarning: A download failure occurred while attempting to retrieve OBXXXX1A_expb.dcm
[   74s]     warnings.warn(
[   74s] 
[   74s] pydicom/data/data_manager.py:365
[   74s]   /home/abuild/rpmbuild/BUILD/pydicom-2.3.0/pydicom/data/data_manager.py:365: UserWarning: A download failure occurred while attempting to retrieve OBXXXX1A_expb_2frame.dcm
[   74s]     warnings.warn(
[   74s] 

@jayvdb
Copy link
Author

jayvdb commented Oct 9, 2022

Those both come from #8

@mrbean-bremen
Copy link
Member

Hm, there may be some version mismatch here. The changes for #8 had been made in pydicom master and are not yet released, while pydicom 2.3.0 should refer to the previous version via the respective commit hash. This will not work though, if the package is installed. As I understand , the pydicom-data 1.0.0 release has been made against master, so these don't match. What we probably need to do is to create pydicom-data releases for the respective pydicom releases and pin pydicom to these.

@mrbean-bremen
Copy link
Member

mrbean-bremen commented Oct 9, 2022

This would only help in future releases, though. I'm not sure how to handle the current problem. One possibiltity I see is to make another pydicom-data release 1.0.1 from the version compatible with pydicom 2.3.0, and make a patch 2.3.1 release that pins pydicom-data to that version. Maybe there is a better solution, this is a bit ugly... @darcymason, what do you think?

@jayvdb
Copy link
Author

jayvdb commented Oct 9, 2022

IIUC, we could wait until pydicom 2.3.1 is released?
I can disable these four tests until then.

@jayvdb
Copy link
Author

jayvdb commented Oct 10, 2022

I've gone ahead and disabled those tests. My %check is now

skips="test_fetch_data_files"
# see https://github.com/pydicom/pydicom-data/issues/9
skips="$skips or OBXXXX1A or (test_can_access_unsupported_dataset and (TestPillowHandler_JPEG or TestPillowHandler_JPEG2K))"

# Failures only on ppc64
skips="$skips or test_invalid_arr_dtype_raises or TestHandlerGenerateMultiplex or TestHandlerMultiplexArray"
# Failures only on i586
skips="$skips or test_write_file_id or test_file_id or test_encapsulate_bot_large_raises or (TestPillowHandler_JPEG2K and test_array)"

# see https://github.com/pydicom/pydicom/issues/1697
ignores="--ignore pydicom/tests/test_dataset.py --ignore pydicom/tests/test_data_manager.py"

%pytest -rs pydicom/tests $ignores -k "not ($skips)"

I've submitted pydicom-data 1.0.0 to openSUSE python packaging team. If that is approved, IMO this issue can be closed and we ignore that there is a minor problem with the 1.0.0 dataset.

@mrbean-bremen
Copy link
Member

Thanks - I think we'll leave this open at least until we have a strategy of how to deal with that.

@darcymason
Copy link
Member

Maybe there is a better solution, this is a bit ugly... @darcymason, what do you think?

I'm still trying to catch up on understanding this. Seems to me there should be a way to avoid the commit hash and only care about the file hashes, at least for the case where pydicom-data is installed. But I'll need at least a couple of days to get a chance to look through the data manager code again.

@mrbean-bremen
Copy link
Member

Yes, for installed versions a filehash makes sense, though in principle it should be sufficient to mak sure the correct version is installed from pip. Not sure where to add that requirement, though... In principle, this could also be used instead of a commit hash, e.g. take the files from a specific branch (or from main, for ongoing development).

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

No branches or pull requests

3 participants