files.new_contents: Header section metadata
  =======================
  
  Tutorial
  --------
  
  One of the primary motivations in writing lasio was to be able to reliably
  parse LAS header sections. This is working well for LAS 1.2 and 2.0
  files, and partially for LAS 3.0 files. 
  
  .. note::
  
     lasio does not require LAS files to be strictly compliant with the standards,
     and you should not expect lasio to raise an exception or error for files which
     are clearly not conforming to the standards. The goal of lasio is to parse
     metadata and data quietly, not to fail unnecessarily.
  
  .. code-block:: python
  
      >>> import lasio.examples
      >>> las = lasio.examples.open('6038187_v1.2_short.las')
  
  The header sections are stored in the dictionary ``las.sections``:
  
  .. code-block:: python
  
      >>> type(las.sections)
      dict
      >>> las.sections.keys()
      dict_keys(['Version', 'Well', 'Curves', 'Parameter', 'Other'])
  
  These are special names reserved for LAS 1.2 and 2.0 files, as defined by the
  standard. Non-standard header sections are also allowed but not fully parsed.
  
  ==============================  =======================================  ===================================================================
  LAS file                        Read in as                               References in ``LASFile``
  ==============================  =======================================  ===================================================================
  ``~v`` or ``~V``                :class:`lasio.SectionItems`              ``LASFile.version`` and ``LASFile.sections['Version']``
  ``~w`` or ``~W``                :class:`lasio.SectionItems`              ``LASFile.well`` and ``LASFile.sections['Well']``
  ``~c`` or ``~C``                :class:`lasio.SectionItems`              ``LASFile.curves`` and ``LASFile.sections['Curves']``
  ``~p`` or ``~P``                :class:`lasio.SectionItems`              ``LASFile.params`` and ``LASFile.sections['Parameter']``
  ``~o`` or ``~O``                ``str``                                  ``LASFile.other`` and ``LASFile.sections['Other']``
  ``~extra section``              ``str``                                  ``LASFile.sections['extra section']``
  ``~a`` or ``~A``                :class:`numpy.ndarray`                   ``LASFile.data`` or each column is in ``LASFile.curves[...].data``
  ==============================  =======================================  ===================================================================
  
  For example:
  
  .. code-block:: python
  
      >>> las.sections['Version']
      [HeaderItem(mnemonic="VERS", unit="", value="2.0", descr="CWLS LOG ASCII STANDA"),
       HeaderItem(mnemonic="WRAP", unit="", value="NO", descr="ONE LINE PER DEPTH STE")]
  
      >>> las.version
      [HeaderItem(mnemonic="VERS", unit="", value="2.0", descr="CWLS LOG ASCII STANDA"),
       HeaderItem(mnemonic
  
  [... the rest is omitted ...]
files.new_path: docs/source/header-section.rst
files.old_contents: Header section metadata
  =======================
  
  Tutorial
  --------
  
  One of the primary motivations in writing lasio was to be able to reliably
  parse LAS header sections. This is working well for LAS 1.2 and 2.0
  files, and partially for LAS 3.0 files. 
  
  .. note::
  
     lasio does not require LAS files to be strictly compliant with the standards,
     and you should not expect lasio to raise an exception or error for files which
     are clearly not conforming to the standards. The goal of lasio is to parse
     metadata and data quietly, not to fail unnecessarily.
  
  .. code-block:: python
  
      >>> import lasio.examples
      >>> las = lasio.examples.open('6038187_v1.2_short.las')
  
  The header sections are stored in the dictionary ``las.sections``:
  
  .. code-block:: python
  
      >>> type(las.sections)
      dict
      >>> las.sections.keys()
      dict_keys(['Version', 'Well', 'Curves', 'Parameter', 'Other'])
  
  These are special names reserved for LAS 1.2 and 2.0 files, as defined by the
  standard. Non-standard header sections are also allowed but not fully parsed.
  
  ==============================  =======================================  ===================================================================
  LAS file                        Read in as                               References in ``LASFile``
  ==============================  =======================================  ===================================================================
  ``~v`` or ``~V``                :class:`lasio.SectionItems`              ``LASFile.version`` and ``LASFile.sections['Version']``
  ``~w`` or ``~W``                :class:`lasio.SectionItems`              ``LASFile.well`` and ``LASFile.sections['Well']``
  ``~c`` or ``~C``                :class:`lasio.SectionItems`              ``LASFile.curves`` and ``LASFile.sections['Curves']``
  ``~p`` or ``~P``                :class:`lasio.SectionItems`              ``LASFile.params`` and ``LASFile.sections['Parameter']``
  ``~o`` or ``~O``                ``str``                                  ``LASFile.other`` and ``LASFile.sections['Other']``
  ``~extra section``              ``str``                                  ``LASFile.sections['extra section']``
  ``~a`` or ``~A``                :class:`numpy.ndarray`                   ``LASFile.data`` or each column is in ``LASFile.curves[...].data``
  ==============================  =======================================  ===================================================================
  
  For example:
  
  .. code-block:: python
  
      >>> las.sections['Version']
      [HeaderItem(mnemonic="VERS", unit="", value="2.0", descr="CWLS LOG ASCII STANDA"),
       HeaderItem(mnemonic="WRAP", unit="", value="NO", descr="ONE LINE PER DEPTH STE")]
  
      >>> las.version
      [HeaderItem(mnemonic="VERS", unit="", value="2.0", descr="CWLS LOG ASCII STANDA"),
       HeaderItem(mnemonic
  
  [... the rest is omitted ...]
files.old_path: docs/source/header-section.rst
files.new_contents: from __future__ import print_function
  
  try:  # will work in Python 3
      from collections.abc import Sequence
  except ImportError:  # Support Python 2.7
      from collections import Sequence
  
  import csv
  import json
  import logging
  import re
  import sys
  import traceback
  
  # get basestring in py3
  
  try:
      unicode = unicode
  except NameError:
      # 'unicode' is undefined, must be Python 3
      unicode = str
      basestring = (str, bytes)
  else:
      # 'unicode' exists, must be Python 2
      bytes = str
      basestring = basestring
  
  # Required third-party packages available on PyPi:
  
  import numpy as np
  
  # internal lasio imports
  
  from . import exceptions
  from .las_items import HeaderItem, CurveItem, SectionItems, OrderedDict
  from . import defaults
  from . import reader
  from . import writer
  
  logger = logging.getLogger(__name__)
  
  
  class LASFile(object):
  
      """LAS file object.
  
      Keyword Arguments:
          file_ref (file-like object, str): either a filename, an open file
              object, or a string containing the contents of a file.
  
      See these routines for additional keyword arguments you can use when
      reading in a LAS file:
  
      * :func:`lasio.reader.open_with_codecs` - manage issues relate to character
        encodings
      * :meth:`lasio.LASFile.read` - control how NULL values and errors are
        handled during parsing
  
      Attributes:
          encoding (str or None): the character encoding used when reading the
              file in from disk
  
      """
  
      def __init__(self, file_ref=None, **read_kwargs):
          super(LASFile, self).__init__()
          self._text = ""
          self.index_unit = None
          self.index_initial = None
          default_items = defaults.get_default_items()
          self.sections = {
              "Version": default_items["Version"],
              "Well": default_items["Well"],
              "Curves": default_items["Curves"],
              "Parameter": default_items["Parameter"],
              "Other": str(default_items["Other"]),
          }
  
          if not (file_ref is None):
              self.read(file_ref, **read_kwargs)
  
      def read(
          self,
          file_ref,
          ignore_header_errors=False,
          ignore_comments=("#",),
          ignore_data_comments="#",
          mnemonic_case="upper",
          ignore_data=False,
          engine="numpy",
          use_normal_engine_for_wrapped=True,
          read_policy="default",
          null_policy="strict",
          index_unit=None,
          dtypes="auto",
          **kwargs
      ):
          """Read a LAS file.
  
          Arguments:
              file_ref (file-like object, str): either a filename, an open file
                  object, or a string containing the contents of a file.
  
          Keyword Arguments:
              ignore_header_errors (bool): ignore LASHeaderErrors (False by
                  default)
              ignore_comments (sequence/str): ignore lines beginning with these
  
  
  [... the rest is omitted ...]
files.new_path: lasio/las.py
files.old_contents: from __future__ import print_function
  
  try:  # will work in Python 3
      from collections.abc import Sequence
  except ImportError:  # Support Python 2.7
      from collections import Sequence
  
  import csv
  import json
  import logging
  import re
  import sys
  import traceback
  
  # get basestring in py3
  
  try:
      unicode = unicode
  except NameError:
      # 'unicode' is undefined, must be Python 3
      unicode = str
      basestring = (str, bytes)
  else:
      # 'unicode' exists, must be Python 2
      bytes = str
      basestring = basestring
  
  # Required third-party packages available on PyPi:
  
  import numpy as np
  
  # internal lasio imports
  
  from . import exceptions
  from .las_items import HeaderItem, CurveItem, SectionItems, OrderedDict
  from . import defaults
  from . import reader
  from . import writer
  
  logger = logging.getLogger(__name__)
  
  
  class LASFile(object):
  
      """LAS file object.
  
      Keyword Arguments:
          file_ref (file-like object, str): either a filename, an open file
              object, or a string containing the contents of a file.
  
      See these routines for additional keyword arguments you can use when
      reading in a LAS file:
  
      * :func:`lasio.reader.open_with_codecs` - manage issues relate to character
        encodings
      * :meth:`lasio.LASFile.read` - control how NULL values and errors are
        handled during parsing
  
      Attributes:
          encoding (str or None): the character encoding used when reading the
              file in from disk
  
      """
  
      def __init__(self, file_ref=None, **read_kwargs):
          super(LASFile, self).__init__()
          self._text = ""
          self.index_unit = None
          self.index_initial = None
          default_items = defaults.get_default_items()
          self.sections = {
              "Version": default_items["Version"],
              "Well": default_items["Well"],
              "Curves": default_items["Curves"],
              "Parameter": default_items["Parameter"],
              "Other": str(default_items["Other"]),
          }
  
          if not (file_ref is None):
              self.read(file_ref, **read_kwargs)
  
      def read(
          self,
          file_ref,
          ignore_header_errors=False,
          ignore_comments=("#",),
          ignore_data_comments="#",
          mnemonic_case="upper",
          ignore_data=False,
          engine="numpy",
          use_normal_engine_for_wrapped=True,
          read_policy="default",
          null_policy="strict",
          index_unit=None,
          dtypes="auto",
          **kwargs
      ):
          """Read a LAS file.
  
          Arguments:
              file_ref (file-like object, str): either a filename, an open file
                  object, or a string containing the contents of a file.
  
          Keyword Arguments:
              ignore_header_errors (bool): ignore LASHeaderErrors (False by
                  default)
              ignore_comments (sequence/str): ignore lines beginning with these
  
  
  [... the rest is omitted ...]
files.old_path: lasio/las.py
files.new_contents: import codecs
  import io
  import logging
  import os
  import re
  import sys
  import traceback
  import urllib.request
  
  import numpy as np
  
  from . import defaults
  
  # Convoluted import for StringIO in order to support:
  #
  # - Python 3 - io.StringIO
  # - Python 2 (optimized) - cStringIO.StringIO
  # - Python 2 (all) - StringIO.StringIO
  
  try:
      import cStringIO as StringIO
  except ImportError:
      try:  # cStringIO not available on this system
          import StringIO
      except ImportError:  # Python 3
          from io import StringIO
      else:
          from StringIO import StringIO
  else:
      from StringIO import StringIO
  
  from . import exceptions
  from .las_items import HeaderItem, CurveItem, SectionItems, OrderedDict
  
  
  logger = logging.getLogger(__name__)
  
  URL_REGEXP = re.compile(
      r"^(?:http|ftp)s?://"  # http:// or https://
      r"(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}"
      r"\.?|[A-Z0-9-]{2,}\.?)|"  # (cont.) domain...
      r"localhost|"  # localhost...
      r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"  # ...or ip
      r"(?::\d+)?"  # optional port
      r"(?:/?|[/?]\S+)$",
      re.IGNORECASE,
  )
  
  # sow (Split On Whitespace) regex
  sow_regex = re.compile(r"""([^\s"']+)|"([^"]*)"|'([^']*)'""")
  
  
  def define_line_splitter(provisional_delimiter):
      """Define multiple line splitters
  
      return the one that is right for the data delmiter
  
      """
      sow_regex = re.compile(r"""([^\s"']+)|"([^"]*)"|'([^']*)'""")
  
      def split_on_whitespace(line):
          return sow_regex.findall(line)
  
      def split_on_comma(line):
          return line.split(",")
  
      splitters = {
          "SPACE": split_on_whitespace,
          "COMMA": split_on_comma,
      }
  
      return splitters[provisional_delimiter]
  
  
  def check_for_path_obj(file_ref):
      """Check if file_ref is a pathlib.Path object.
  
      If file_ref is a pathlib.Path object, then return its absolute file
      path as a string so it will get processed as other string filenames.
  
      If pathlib is not available, do nothing and return file_ref.
  
      """
      try:
          from pathlib import Path
      except ImportError:
          return file_ref
  
      if isinstance(file_ref, Path):
          return file_ref.absolute
  
  [... the rest is omitted ...]
files.new_path: lasio/reader.py
files.old_contents: import codecs
  import io
  import logging
  import os
  import re
  import sys
  import traceback
  import urllib.request
  
  import numpy as np
  
  from . import defaults
  
  # Convoluted import for StringIO in order to support:
  #
  # - Python 3 - io.StringIO
  # - Python 2 (optimized) - cStringIO.StringIO
  # - Python 2 (all) - StringIO.StringIO
  
  try:
      import cStringIO as StringIO
  except ImportError:
      try:  # cStringIO not available on this system
          import StringIO
      except ImportError:  # Python 3
          from io import StringIO
      else:
          from StringIO import StringIO
  else:
      from StringIO import StringIO
  
  from . import exceptions
  from .las_items import HeaderItem, CurveItem, SectionItems, OrderedDict
  
  
  logger = logging.getLogger(__name__)
  
  URL_REGEXP = re.compile(
      r"^(?:http|ftp)s?://"  # http:// or https://
      r"(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}"
      r"\.?|[A-Z0-9-]{2,}\.?)|"  # (cont.) domain...
      r"localhost|"  # localhost...
      r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"  # ...or ip
      r"(?::\d+)?"  # optional port
      r"(?:/?|[/?]\S+)$",
      re.IGNORECASE,
  )
  
  # sow (Split On Whitespace) regex
  sow_regex = re.compile(r"""([^\s"']+)|"([^"]*)"|'([^']*)'""")
  
  
  def define_line_splitter(provisional_delimiter):
      """Define multiple line splitters
  
      return the one that is right for the data delmiter
  
      """
      sow_regex = re.compile(r"""([^\s"']+)|"([^"]*)"|'([^']*)'""")
  
      def split_on_whitespace(line):
          return sow_regex.findall(line)
  
      def split_on_comma(line):
          return line.split(",")
  
      splitters = {
          "SPACE": split_on_whitespace,
          "COMMA": split_on_comma,
      }
  
      return splitters[provisional_delimiter]
  
  
  def check_for_path_obj(file_ref):
      """Check if file_ref is a pathlib.Path object.
  
      If file_ref is a pathlib.Path object, then return its absolute file
      path as a string so it will get processed as other string filenames.
  
      If pathlib is not available, do nothing and return file_ref.
  
      """
      try:
          from pathlib import Path
      except ImportError:
          return file_ref
  
      if isinstance(file_ref, Path):
          return file_ref.absolute
  
  [... the rest is omitted ...]
files.old_path: lasio/reader.py