@classmethod
    def _readfrom_internal(cls, data, header=None, checksum=False,
                           ignore_missing_end=False, **kwargs):
        """
        Provides the bulk of the internal implementation for readfrom and
        fromstring.

        For some special cases, supports using a header that was already
        created, and just using the input data for the actual array data.
        """

        hdu_buffer = None
        hdu_fileobj = None
        header_offset = 0

        if isinstance(data, _File):
            from_file = True
            if header is None:
                header_offset = data.tell()
                header = Header.fromfile(data, endcard=not ignore_missing_end)
            hdu_fileobj = data
            data_offset = data.tell()  # *after* reading the header
        else:
            from_file = False
            try:
                # Test that the given object supports the buffer interface by
                # ensuring an ndarray can be created from it
                np.ndarray((), dtype='ubyte', buffer=data)
            except TypeError:
                raise TypeError(
                    'The provided object %r does not contain an underlying '
                    'memory buffer.  fromstring() requires an object that '
                    'supports the buffer interface such as bytes, str '
                    '(in Python 2.x but not in 3.x), buffer, memoryview, '
                    'ndarray, etc.  This restriction is to ensure that '
                    'efficient access to the array/table data is possible.'
                    % data)

            if header is None:
                def block_iter(nbytes):
                    idx = 0
                    while idx < len(data):
                        yield data[idx:idx + nbytes]
                        idx += nbytes

                header_str, header = Header._from_blocks(
                    block_iter, True, '', not ignore_missing_end, True)

                if len(data) > len(header_str):
                    hdu_buffer = data
            elif data:
                hdu_buffer = data

            header_offset = 0
            data_offset = len(header_str)

        # Determine the appropriate arguments to pass to the constructor from
        # self._kwargs.  self._kwargs contains any number of optional arguments
        # that may or may not be valid depending on the HDU type
        cls = _hdu_class_from_header(cls, header)
        args, varargs, varkwargs, defaults = getargspec(cls.__init__)
        new_kwargs = kwargs.copy()
        if not varkwargs:
            # If __init__ accepts arbitrary keyword arguments, then we can go
            # ahead and pass all keyword arguments; otherwise we need to delete
            # any that are invalid
            for key in kwargs:
                if key not in args:
                    del new_kwargs[key]

        hdu = cls(data=DELAYED, header=header, **new_kwargs)

        # One of these may be None, depending on whether the data came from a
        # file or a string buffer--later this will be further abstracted
        hdu._file = hdu_fileobj
        hdu._buffer = hdu_buffer

        hdu._header_offset = header_offset     # beginning of the header area
        hdu._data_offset = data_offset         # beginning of the data area

        # data area size, including padding
        size = hdu.size
        hdu._data_size = size + _pad_length(size)

        # Checksums are not checked on invalid HDU types
        if checksum and checksum != 'remove' and isinstance(hdu, _ValidHDU):
            hdu._verify_checksum_datasum(checksum)

        return hdu
dataset/ETHPy150Open spacetelescope/PyFITS/pyfits/hdu/base.py/_BaseHDU._readfrom_internal/original