prompt: 
  We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  pydicom should not define handler, formatter and log level.
  The `config` module (imported when pydicom is imported) defines a handler and set the log level for the pydicom logger. This should not be the case IMO. It should be the responsibility of the client code of pydicom to configure the logging module to its convenience. Otherwise one end up having multiple logs record as soon as pydicom is imported:
  
  Example:
  ```
  Could not import pillow
  2018-03-25 15:27:29,744 :: DEBUG :: pydicom 
    Could not import pillow
  Could not import jpeg_ls
  2018-03-25 15:27:29,745 :: DEBUG :: pydicom 
    Could not import jpeg_ls
  Could not import gdcm
  2018-03-25 15:27:29,745 :: DEBUG :: pydicom 
    Could not import gdcm
  ``` 
  Or am I missing something?
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  
  --- BEGIN FILE ---
  ```
  ### pydicom/config.py
  # Copyright 2008-2018 pydicom authors. See LICENSE file for details.
  """Pydicom configuration options."""
  
  # doc strings following items are picked up by sphinx for documentation
  
  import logging
  
  # Set the type used to hold DS values
  #    default False; was decimal-based in pydicom 0.9.7
  use_DS_decimal = False
  
  
  data_element_callback = None
  """Set data_element_callback to a function to be called from read_dataset
  every time a RawDataElement has been returned, before it is added
  to the dataset.
  """
  
  data_element_callback_kwargs = {}
  """Set this to use as keyword arguments passed to the data_element_callback
  function"""
  
  
  def reset_data_element_callback():
      global data_element_callback
      global data_element_callback_kwargs
      data_element_callback = None
      data_element_callback_kwargs = {}
  
  
  def DS_decimal(use_Decimal_boolean=True):
      """Set DS class to be derived from Decimal (True) or from float (False)
      If this function is never called, the default in pydicom >= 0.9.8
      is for DS to be based on float.
      """
      use_DS_decimal = use_Decimal_boolean
      import pydicom.valuerep
      if use_DS_decimal:
          pydicom.valuerep.DSclass = pydicom.valuerep.DSdecimal
      else:
          pydicom.valuerep.DSclass = pydicom.valuerep.DSfloat
  
  
  # Configuration flags
  allow_DS_float = False
  """Set allow_float to True to allow DSdecimal instances
  to be created with floats; otherwise, they must be explicitly
  converted to strings, with the user explicity setting the
  precision of digits and rounding. Default: False"""
  
  enforce_valid_values = False
  """Raise errors if any value is not allowed by DICOM standard,
  e.g. DS strings that are longer than 16 characters;
  IS strings outside the allowed range.
  """
  
  datetime_conversion = False
  """Set datetime_conversion to convert DA, DT and TM
  data elements to datetime.date, datetime.datetime
  and datetime.time respectively. Default: False
  """
  
  # Logging system and debug function to change logging level
  logger = logging.getLogger('pydicom')
  handler = logging.StreamHandler()
  formatter = logging.Formatter("%(message)s")
  handler.setFormatter(formatter)
  logger.addHandler(handler)
  
  
  import pydicom.pixel_data_handlers.numpy_handler as np_handler  # noqa
  import pydicom.pixel_data_handlers.rle_handler as rle_handler  # noqa
  import pydicom.pixel_data_handlers.pillow_handler as pillow_handler  # noqa
  import pydicom.pixel_data_handlers.jpeg_ls_handler as jpegls_handler  # noqa
  import pydicom.pixel_data_handlers.gdcm_handler as gdcm_handler  # noqa
  
  pixel_data_handlers = [
      np_handler,
      rle_handler,
      gdcm_handler,
      pillow_handler,
      jpegls_handler,
  ]
  """Handlers for converting (7fe0,0010) Pixel Data.
  This is an ordered list that the dataset.convert_pixel_data()
  method will try to extract a correctly sized numpy array from the
  PixelData element.
  
  Handers shall have two methods:
  
  def supports_transfer_syntax(ds)
    This returns True if the handler might support the transfer syntax
    indicated in the dicom_dataset
  
  def get_pixeldata(ds):
    This shall either throw an exception or return a correctly sized numpy
    array derived from the PixelData.  Reshaping the array to the correct
    dimensions is handled outside the image handler
  
  The first handler that both announces that it supports the transfer syntax
  and does not throw an exception, either in getting the data or when the data
  is reshaped to the correct dimensions, is the handler that will provide the
  data.
  
  If they all fail, the last one to throw an exception gets to see its
  exception thrown up.
  
  If no one throws an exception, but they all refuse to support the transfer
  syntax, then this fact is announced in a NotImplementedError exception.
  """
  
  
  def debug(debug_on=True):
      """Turn debugging of DICOM file reading and writing on or off.
      When debugging is on, file location and details about the
      elements read at that location are logged to the 'pydicom'
      logger using python's logging module.
  
      :param debug_on: True (default) to turn on debugging,
      False to turn off.
      """
      global logger, debugging
      if debug_on:
          logger.setLevel(logging.DEBUG)
          debugging = True
      else:
          logger.setLevel(logging.WARNING)
          debugging = False
  
  
  # force level=WARNING, in case logging default is set differently (issue 103)
  debug(False)
  
  ```
  --- END FILE ---
  
  Please first localize the bug based on the issue statement, and then generate *SEARCH/REPLACE* edits to fix the issue.
  
  Every *SEARCH/REPLACE* edit must use this format:
  1. The file path
  2. The start of search block: <<<<<<< SEARCH
  3. A contiguous chunk of lines to search for in the existing source code
  4. The dividing line: =======
  5. The lines to replace into the source code
  6. The end of the replace block: >>>>>>> REPLACE
  
  Here is an example:
  
  ```python
  ### mathweb/flask/app.py
  <<<<<<< SEARCH
  from flask import Flask
  =======
  import math
  from flask import Flask
  >>>>>>> REPLACE
  ```
  
  Please note that the *SEARCH/REPLACE* edit REQUIRES PROPER INDENTATION. If you would like to add the line '        print(x)', you must fully write that out, with all those spaces before the code!
  Wrap the *SEARCH/REPLACE* edit in blocks ```python...```.
  
instance: {"FAIL_TO_PASS": "[\"pydicom/tests/test_config.py::TestDebug::test_default\", \"pydicom/tests/test_config.py::TestDebug::test_debug_on_handler_null\", \"pydicom/tests/test_config.py::TestDebug::test_debug_off_handler_null\", \"pydicom/tests/test_config.py::TestDebug::test_debug_on_handler_stream\", \"pydicom/tests/test_config.py::TestDebug::test_debug_off_handler_stream\"]", "PASS_TO_PASS": "[]", "base_commit": "3746878d8edf1cbda6fbcf35eec69f9ba79301ca", "created_at": "2019-07-27T00:18:11Z", "environment_setup_commit": "7241f5d9db0de589b230bb84212fbb643a7c86c3", "hints_text": "In addition, I don't understand what the purpose of the `config.debug` function since the default behavor of the logging module in absence of configuartion seems to already be the one you want.\r\n\r\nFrom https://docs.python.org/3/howto/logging.html#configuring-logging-for-a-library:\r\n\r\n> If the using application does not use logging, and library code makes logging calls, then (as described in the previous section) events of severity WARNING and greater will be printed to sys.stderr. This is regarded as the best default behaviour.\r\n\r\nand\r\n\r\n>**It is strongly advised that you do not add any handlers other than NullHandler to your library\u2019s loggers.** This is because the configuration of handlers is the prerogative of the application developer who uses your library. The application developer knows their target audience and what handlers are most appropriate for their application: if you add handlers \u2018under the hood\u2019, you might well interfere with their ability to carry out unit tests and deliver logs which suit their requirements. \r\n\nI think you make good points here.  I support changing the logging to comply with python's suggested behavior.\r\n\r\n> In addition, I don't understand what the purpose of the config.debug function\r\n\r\nOne reason is that the core loop in pydicom (data_element_generator in filereader.py) is extremely optimized for speed - it checks the `debugging` flag set by config.debug, to avoid composing messages and doing function calls to logger when not needed.", "instance_id": "pydicom__pydicom-901", "patch": "diff --git a/pydicom/config.py b/pydicom/config.py\n--- a/pydicom/config.py\n+++ b/pydicom/config.py\n@@ -62,10 +62,7 @@ def DS_decimal(use_Decimal_boolean=True):\n \n # Logging system and debug function to change logging level\n logger = logging.getLogger('pydicom')\n-handler = logging.StreamHandler()\n-formatter = logging.Formatter(\"%(message)s\")\n-handler.setFormatter(formatter)\n-logger.addHandler(handler)\n+logger.addHandler(logging.NullHandler())\n \n \n import pydicom.pixel_data_handlers.numpy_handler as np_handler  # noqa\n@@ -110,16 +107,29 @@ def get_pixeldata(ds):\n \"\"\"\n \n \n-def debug(debug_on=True):\n-    \"\"\"Turn debugging of DICOM file reading and writing on or off.\n+def debug(debug_on=True, default_handler=True):\n+    \"\"\"Turn on/off debugging of DICOM file reading and writing.\n+\n     When debugging is on, file location and details about the\n     elements read at that location are logged to the 'pydicom'\n     logger using python's logging module.\n \n-    :param debug_on: True (default) to turn on debugging,\n-    False to turn off.\n+    Parameters\n+    ----------\n+    debug_on : bool, optional\n+        If True (default) then turn on debugging, False to turn off.\n+    default_handler : bool, optional\n+        If True (default) then use ``logging.StreamHandler()`` as the handler\n+        for log messages.\n     \"\"\"\n     global logger, debugging\n+\n+    if default_handler:\n+        handler = logging.StreamHandler()\n+        formatter = logging.Formatter(\"%(message)s\")\n+        handler.setFormatter(formatter)\n+        logger.addHandler(handler)\n+\n     if debug_on:\n         logger.setLevel(logging.DEBUG)\n         debugging = True\n@@ -129,4 +139,4 @@ def debug(debug_on=True):\n \n \n # force level=WARNING, in case logging default is set differently (issue 103)\n-debug(False)\n+debug(False, False)\n", "problem_statement": "pydicom should not define handler, formatter and log level.\nThe `config` module (imported when pydicom is imported) defines a handler and set the log level for the pydicom logger. This should not be the case IMO. It should be the responsibility of the client code of pydicom to configure the logging module to its convenience. Otherwise one end up having multiple logs record as soon as pydicom is imported:\r\n\r\nExample:\r\n```\r\nCould not import pillow\r\n2018-03-25 15:27:29,744 :: DEBUG :: pydicom \r\n  Could not import pillow\r\nCould not import jpeg_ls\r\n2018-03-25 15:27:29,745 :: DEBUG :: pydicom \r\n  Could not import jpeg_ls\r\nCould not import gdcm\r\n2018-03-25 15:27:29,745 :: DEBUG :: pydicom \r\n  Could not import gdcm\r\n``` \r\nOr am I missing something?\n", "repo": "pydicom/pydicom", "test_patch": "diff --git a/pydicom/tests/test_config.py b/pydicom/tests/test_config.py\nnew file mode 100644\n--- /dev/null\n+++ b/pydicom/tests/test_config.py\n@@ -0,0 +1,107 @@\n+# Copyright 2008-2019 pydicom authors. See LICENSE file for details.\n+\"\"\"Unit tests for the pydicom.config module.\"\"\"\n+\n+import logging\n+import sys\n+\n+import pytest\n+\n+from pydicom import dcmread\n+from pydicom.config import debug\n+from pydicom.data import get_testdata_files\n+\n+\n+DS_PATH = get_testdata_files(\"CT_small.dcm\")[0]\n+PYTEST = [int(x) for x in pytest.__version__.split('.')]\n+\n+\n+@pytest.mark.skipif(PYTEST[:2] < [3, 4], reason='no caplog')\n+class TestDebug(object):\n+    \"\"\"Tests for config.debug().\"\"\"\n+    def setup(self):\n+        self.logger = logging.getLogger('pydicom')\n+\n+    def teardown(self):\n+        # Reset to just NullHandler\n+        self.logger.handlers = [self.logger.handlers[0]]\n+\n+    def test_default(self, caplog):\n+        \"\"\"Test that the default logging handler is a NullHandler.\"\"\"\n+        assert 1 == len(self.logger.handlers)\n+        assert isinstance(self.logger.handlers[0], logging.NullHandler)\n+\n+        with caplog.at_level(logging.DEBUG, logger='pydicom'):\n+            ds = dcmread(DS_PATH)\n+\n+            assert \"Call to dcmread()\" not in caplog.text\n+            assert \"Reading File Meta Information preamble...\" in caplog.text\n+            assert \"Reading File Meta Information prefix...\" in caplog.text\n+            assert \"00000080: 'DICM' prefix found\" in caplog.text\n+\n+    def test_debug_on_handler_null(self, caplog):\n+        \"\"\"Test debug(True, False).\"\"\"\n+        debug(True, False)\n+        assert 1 == len(self.logger.handlers)\n+        assert isinstance(self.logger.handlers[0], logging.NullHandler)\n+\n+        with caplog.at_level(logging.DEBUG, logger='pydicom'):\n+            ds = dcmread(DS_PATH)\n+\n+            assert \"Call to dcmread()\" in caplog.text\n+            assert \"Reading File Meta Information preamble...\" in caplog.text\n+            assert \"Reading File Meta Information prefix...\" in caplog.text\n+            assert \"00000080: 'DICM' prefix found\" in caplog.text\n+            msg = (\n+                \"00009848: fc ff fc ff 4f 42 00 00 7e 00 00 00    \"\n+                \"(fffc, fffc) OB Length: 126\"\n+            )\n+            assert msg in caplog.text\n+\n+    def test_debug_off_handler_null(self, caplog):\n+        \"\"\"Test debug(False, False).\"\"\"\n+        debug(False, False)\n+        assert 1 == len(self.logger.handlers)\n+        assert isinstance(self.logger.handlers[0], logging.NullHandler)\n+\n+        with caplog.at_level(logging.DEBUG, logger='pydicom'):\n+            ds = dcmread(DS_PATH)\n+\n+            assert \"Call to dcmread()\" not in caplog.text\n+            assert \"Reading File Meta Information preamble...\" in caplog.text\n+            assert \"Reading File Meta Information prefix...\" in caplog.text\n+            assert \"00000080: 'DICM' prefix found\" in caplog.text\n+\n+    def test_debug_on_handler_stream(self, caplog):\n+        \"\"\"Test debug(True, True).\"\"\"\n+        debug(True, True)\n+        assert 2 == len(self.logger.handlers)\n+        assert isinstance(self.logger.handlers[0], logging.NullHandler)\n+        assert isinstance(self.logger.handlers[1], logging.StreamHandler)\n+\n+        with caplog.at_level(logging.DEBUG, logger='pydicom'):\n+            ds = dcmread(DS_PATH)\n+\n+            assert \"Call to dcmread()\" in caplog.text\n+            assert \"Reading File Meta Information preamble...\" in caplog.text\n+            assert \"Reading File Meta Information prefix...\" in caplog.text\n+            assert \"00000080: 'DICM' prefix found\" in caplog.text\n+            msg = (\n+                \"00009848: fc ff fc ff 4f 42 00 00 7e 00 00 00    \"\n+                \"(fffc, fffc) OB Length: 126\"\n+            )\n+            assert msg in caplog.text\n+\n+    def test_debug_off_handler_stream(self, caplog):\n+        \"\"\"Test debug(False, True).\"\"\"\n+        debug(False, True)\n+        assert 2 == len(self.logger.handlers)\n+        assert isinstance(self.logger.handlers[0], logging.NullHandler)\n+        assert isinstance(self.logger.handlers[1], logging.StreamHandler)\n+\n+        with caplog.at_level(logging.DEBUG, logger='pydicom'):\n+            ds = dcmread(DS_PATH)\n+\n+            assert \"Call to dcmread()\" not in caplog.text\n+            assert \"Reading File Meta Information preamble...\" in caplog.text\n+            assert \"Reading File Meta Information prefix...\" in caplog.text\n+            assert \"00000080: 'DICM' prefix found\" in caplog.text\n", "version": "1.3"}
parsed_commit_content: {"file_diffs":[{"old_file_content":"# Copyright 2008-2018 pydicom authors. See LICENSE file for details.\n\"\"\"Pydicom configuration options.\"\"\"\n\n# doc strings following items are picked up by sphinx for documentation\n\nimport logging\n\n# Set the type used to hold DS values\n#    default False; was decimal-based in pydicom 0.9.7\nuse_DS_decimal = False\n\n\ndata_element_callback = None\n\"\"\"Set data_element_callback to a function to be called from read_dataset\nevery time a RawDataElement has been returned, before it is added\nto the dataset.\n\"\"\"\n\ndata_element_callback_kwargs = {}\n\"\"\"Set this to use as keyword arguments passed to the data_element_callback\nfunction\"\"\"\n\n\ndef reset_data_element_callback():\n    global data_element_callback\n    global data_element_callback_kwargs\n    data_element_callback = None\n    data_element_callback_kwargs = {}\n\n\ndef DS_decimal(use_Decimal_boolean=True):\n    \"\"\"Set DS class to be derived from Decimal (True) or from float (False)\n    If this function is never called, the default in pydicom >= 0.9.8\n    is for DS to be based on float.\n    \"\"\"\n    use_DS_decimal = use_Decimal_boolean\n    import pydicom.valuerep\n    if use_DS_decimal:\n        pydicom.valuerep.DSclass = pydicom.valuerep.DSdecimal\n    else:\n        pydicom.valuerep.DSclass = pydicom.valuerep.DSfloat\n\n\n# Configuration flags\nallow_DS_float = False\n\"\"\"Set allow_float to True to allow DSdecimal instances\nto be created with floats; otherwise, they must be explicitly\nconverted to strings, with the user explicity setting the\nprecision of digits and rounding. Default: False\"\"\"\n\nenforce_valid_values = False\n\"\"\"Raise errors if any value is not allowed by DICOM standard,\ne.g. DS strings that are longer than 16 characters;\nIS strings outside the allowed range.\n\"\"\"\n\ndatetime_conversion = False\n\"\"\"Set datetime_conversion to convert DA, DT and TM\ndata elements to datetime.date, datetime.datetime\nand datetime.time respectively. Default: False\n\"\"\"\n\n# Logging system and debug function to change logging level\nlogger = logging.getLogger('pydicom')\nhandler = logging.StreamHandler()\nformatter = logging.Formatter(\"%(message)s\")\nhandler.setFormatter(formatter)\nlogger.addHandler(handler)\n\n\nimport pydicom.pixel_data_handlers.numpy_handler as np_handler  # noqa\nimport pydicom.pixel_data_handlers.rle_handler as rle_handler  # noqa\nimport pydicom.pixel_data_handlers.pillow_handler as pillow_handler  # noqa\nimport pydicom.pixel_data_handlers.jpeg_ls_handler as jpegls_handler  # noqa\nimport pydicom.pixel_data_handlers.gdcm_handler as gdcm_handler  # noqa\n\npixel_data_handlers = [\n    np_handler,\n    rle_handler,\n    gdcm_handler,\n    pillow_handler,\n    jpegls_handler,\n]\n\"\"\"Handlers for converting (7fe0,0010) Pixel Data.\nThis is an ordered list that the dataset.convert_pixel_data()\nmethod will try to extract a correctly sized numpy array from the\nPixelData element.\n\nHanders shall have two methods:\n\ndef supports_transfer_syntax(ds)\n  This returns True if the handler might support the transfer syntax\n  indicated in the dicom_dataset\n\ndef get_pixeldata(ds):\n  This shall either throw an exception or return a correctly sized numpy\n  array derived from the PixelData.  Reshaping the array to the correct\n  dimensions is handled outside the image handler\n\nThe first handler that both announces that it supports the transfer syntax\nand does not throw an exception, either in getting the data or when the data\nis reshaped to the correct dimensions, is the handler that will provide the\ndata.\n\nIf they all fail, the last one to throw an exception gets to see its\nexception thrown up.\n\nIf no one throws an exception, but they all refuse to support the transfer\nsyntax, then this fact is announced in a NotImplementedError exception.\n\"\"\"\n\n\ndef debug(debug_on=True):\n    \"\"\"Turn debugging of DICOM file reading and writing on or off.\n    When debugging is on, file location and details about the\n    elements read at that location are logged to the 'pydicom'\n    logger using python's logging module.\n\n    :param debug_on: True (default) to turn on debugging,\n    False to turn off.\n    \"\"\"\n    global logger, debugging\n    if debug_on:\n        logger.setLevel(logging.DEBUG)\n        debugging = True\n    else:\n        logger.setLevel(logging.WARNING)\n        debugging = False\n\n\n# force level=WARNING, in case logging default is set differently (issue 103)\ndebug(False)\n","new_file_content":"# Copyright 2008-2018 pydicom authors. See LICENSE file for details.\n\"\"\"Pydicom configuration options.\"\"\"\n\n# doc strings following items are picked up by sphinx for documentation\n\nimport logging\n\n# Set the type used to hold DS values\n#    default False; was decimal-based in pydicom 0.9.7\nuse_DS_decimal = False\n\n\ndata_element_callback = None\n\"\"\"Set data_element_callback to a function to be called from read_dataset\nevery time a RawDataElement has been returned, before it is added\nto the dataset.\n\"\"\"\n\ndata_element_callback_kwargs = {}\n\"\"\"Set this to use as keyword arguments passed to the data_element_callback\nfunction\"\"\"\n\n\ndef reset_data_element_callback():\n    global data_element_callback\n    global data_element_callback_kwargs\n    data_element_callback = None\n    data_element_callback_kwargs = {}\n\n\ndef DS_decimal(use_Decimal_boolean=True):\n    \"\"\"Set DS class to be derived from Decimal (True) or from float (False)\n    If this function is never called, the default in pydicom >= 0.9.8\n    is for DS to be based on float.\n    \"\"\"\n    use_DS_decimal = use_Decimal_boolean\n    import pydicom.valuerep\n    if use_DS_decimal:\n        pydicom.valuerep.DSclass = pydicom.valuerep.DSdecimal\n    else:\n        pydicom.valuerep.DSclass = pydicom.valuerep.DSfloat\n\n\n# Configuration flags\nallow_DS_float = False\n\"\"\"Set allow_float to True to allow DSdecimal instances\nto be created with floats; otherwise, they must be explicitly\nconverted to strings, with the user explicity setting the\nprecision of digits and rounding. Default: False\"\"\"\n\nenforce_valid_values = False\n\"\"\"Raise errors if any value is not allowed by DICOM standard,\ne.g. DS strings that are longer than 16 characters;\nIS strings outside the allowed range.\n\"\"\"\n\ndatetime_conversion = False\n\"\"\"Set datetime_conversion to convert DA, DT and TM\ndata elements to datetime.date, datetime.datetime\nand datetime.time respectively. Default: False\n\"\"\"\n\n# Logging system and debug function to change logging level\nlogger = logging.getLogger('pydicom')\nlogger.addHandler(logging.NullHandler())\n\n\nimport pydicom.pixel_data_handlers.numpy_handler as np_handler  # noqa\nimport pydicom.pixel_data_handlers.rle_handler as rle_handler  # noqa\nimport pydicom.pixel_data_handlers.pillow_handler as pillow_handler  # noqa\nimport pydicom.pixel_data_handlers.jpeg_ls_handler as jpegls_handler  # noqa\nimport pydicom.pixel_data_handlers.gdcm_handler as gdcm_handler  # noqa\n\npixel_data_handlers = [\n    np_handler,\n    rle_handler,\n    gdcm_handler,\n    pillow_handler,\n    jpegls_handler,\n]\n\"\"\"Handlers for converting (7fe0,0010) Pixel Data.\nThis is an ordered list that the dataset.convert_pixel_data()\nmethod will try to extract a correctly sized numpy array from the\nPixelData element.\n\nHanders shall have two methods:\n\ndef supports_transfer_syntax(ds)\n  This returns True if the handler might support the transfer syntax\n  indicated in the dicom_dataset\n\ndef get_pixeldata(ds):\n  This shall either throw an exception or return a correctly sized numpy\n  array derived from the PixelData.  Reshaping the array to the correct\n  dimensions is handled outside the image handler\n\nThe first handler that both announces that it supports the transfer syntax\nand does not throw an exception, either in getting the data or when the data\nis reshaped to the correct dimensions, is the handler that will provide the\ndata.\n\nIf they all fail, the last one to throw an exception gets to see its\nexception thrown up.\n\nIf no one throws an exception, but they all refuse to support the transfer\nsyntax, then this fact is announced in a NotImplementedError exception.\n\"\"\"\n\n\ndef debug(debug_on=True, default_handler=True):\n    \"\"\"Turn on/off debugging of DICOM file reading and writing.\n\n    When debugging is on, file location and details about the\n    elements read at that location are logged to the 'pydicom'\n    logger using python's logging module.\n\n    Parameters\n    ----------\n    debug_on : bool, optional\n        If True (default) then turn on debugging, False to turn off.\n    default_handler : bool, optional\n        If True (default) then use ``logging.StreamHandler()`` as the handler\n        for log messages.\n    \"\"\"\n    global logger, debugging\n\n    if default_handler:\n        handler = logging.StreamHandler()\n        formatter = logging.Formatter(\"%(message)s\")\n        handler.setFormatter(formatter)\n        logger.addHandler(handler)\n\n    if debug_on:\n        logger.setLevel(logging.DEBUG)\n        debugging = True\n    else:\n        logger.setLevel(logging.WARNING)\n        debugging = False\n\n\n# force level=WARNING, in case logging default is set differently (issue 103)\ndebug(False, False)\n","header":{"file":{"path":"pydicom/config.py"},"misc_line":null},"index_line":null,"is_binary_file":false,"binary_line":null,"minus_file":{"path":"a/pydicom/config.py"},"plus_file":{"path":"b/pydicom/config.py"},"hunks":[{"descriptor":{"old_range":{"start":62,"length":10},"new_range":{"start":62,"length":7},"section":"def DS_decimal(use_Decimal_boolean=True):"},"line_group":{"all_lines":[{"content":"","type":"context"},{"content":"# Logging system and debug function to change logging level","type":"context"},{"content":"logger = logging.getLogger('pydicom')","type":"context"},{"content":"handler = logging.StreamHandler()","type":"deleted"},{"content":"formatter = logging.Formatter(\"%(message)s\")","type":"deleted"},{"content":"handler.setFormatter(formatter)","type":"deleted"},{"content":"logger.addHandler(handler)","type":"deleted"},{"content":"logger.addHandler(logging.NullHandler())","type":"added"},{"content":"","type":"context"},{"content":"","type":"context"},{"content":"import pydicom.pixel_data_handlers.numpy_handler as np_handler  # noqa","type":"context"}]},"modified_entities":[],"added_entities":[],"deleted_entities":[]},{"descriptor":{"old_range":{"start":110,"length":16},"new_range":{"start":107,"length":29},"section":"def get_pixeldata(ds):"},"line_group":{"all_lines":[{"content":"\"\"\"","type":"context"},{"content":"","type":"context"},{"content":"","type":"context"},{"content":"def debug(debug_on=True):","type":"deleted"},{"content":"    \"\"\"Turn debugging of DICOM file reading and writing on or off.","type":"deleted"},{"content":"def debug(debug_on=True, default_handler=True):","type":"added"},{"content":"    \"\"\"Turn on/off debugging of DICOM file reading and writing.","type":"added"},{"content":"","type":"added"},{"content":"    When debugging is on, file location and details about the","type":"context"},{"content":"    elements read at that location are logged to the 'pydicom'","type":"context"},{"content":"    logger using python's logging module.","type":"context"},{"content":"","type":"context"},{"content":"    :param debug_on: True (default) to turn on debugging,","type":"deleted"},{"content":"    False to turn off.","type":"deleted"},{"content":"    Parameters","type":"added"},{"content":"    ----------","type":"added"},{"content":"    debug_on : bool, optional","type":"added"},{"content":"        If True (default) then turn on debugging, False to turn off.","type":"added"},{"content":"    default_handler : bool, optional","type":"added"},{"content":"        If True (default) then use ``logging.StreamHandler()`` as the handler","type":"added"},{"content":"        for log messages.","type":"added"},{"content":"    \"\"\"","type":"context"},{"content":"    global logger, debugging","type":"context"},{"content":"","type":"added"},{"content":"    if default_handler:","type":"added"},{"content":"        handler = logging.StreamHandler()","type":"added"},{"content":"        formatter = logging.Formatter(\"%(message)s\")","type":"added"},{"content":"        handler.setFormatter(formatter)","type":"added"},{"content":"        logger.addHandler(handler)","type":"added"},{"content":"","type":"added"},{"content":"    if debug_on:","type":"context"},{"content":"        logger.setLevel(logging.DEBUG)","type":"context"},{"content":"        debugging = True","type":"context"}]},"modified_entities":[],"added_entities":[],"deleted_entities":[]},{"descriptor":{"old_range":{"start":129,"length":4},"new_range":{"start":139,"length":4},"section":"def debug(debug_on=True):"},"line_group":{"all_lines":[{"content":"","type":"context"},{"content":"","type":"context"},{"content":"# force level=WARNING, in case logging default is set differently (issue 103)","type":"context"},{"content":"debug(False)","type":"deleted"},{"content":"debug(False, False)","type":"added"},{"content":"","type":"context"}]},"modified_entities":[],"added_entities":[],"deleted_entities":[]}]}],"old_commit_hash":"3746878d8edf1cbda6fbcf35eec69f9ba79301ca","new_commit_hash":"56ea2a136a213ddd85f7a193d9cce840da7aab8a","commit_message":"Remove unnecessary line","commit_date":"2019-07-28T09:04:59+10:00","metadata":{}}
problem_statement: pydicom should not define handler, formatter and log level.
  The `config` module (imported when pydicom is imported) defines a handler and set the log level for the pydicom logger. This should not be the case IMO. It should be the responsibility of the client code of pydicom to configure the logging module to its convenience. Otherwise one end up having multiple logs record as soon as pydicom is imported:
  
  Example:
  ```
  Could not import pillow
  2018-03-25 15:27:29,744 :: DEBUG :: pydicom 
    Could not import pillow
  Could not import jpeg_ls
  2018-03-25 15:27:29,745 :: DEBUG :: pydicom 
    Could not import jpeg_ls
  Could not import gdcm
  2018-03-25 15:27:29,745 :: DEBUG :: pydicom 
    Could not import gdcm
  ``` 
  Or am I missing something?
  
patch: diff --git a/pydicom/config.py b/pydicom/config.py
  --- a/pydicom/config.py
  +++ b/pydicom/config.py
  @@ -62,10 +62,7 @@ def DS_decimal(use_Decimal_boolean=True):
   
   # Logging system and debug function to change logging level
   logger = logging.getLogger('pydicom')
  -handler = logging.StreamHandler()
  -formatter = logging.Formatter("%(message)s")
  -handler.setFormatter(formatter)
  -logger.addHandler(handler)
  +logger.addHandler(logging.NullHandler())
   
   
   import pydicom.pixel_data_handlers.numpy_handler as np_handler  # noqa
  @@ -110,16 +107,29 @@ def get_pixeldata(ds):
   """
   
   
  -def debug(debug_on=True):
  -    """Turn debugging of DICOM file reading and writing on or off.
  +def debug(debug_on=True, default_handler=True):
  +    """Turn on/off debugging of DICOM file reading and writing.
  +
       When debugging is on, file location and details about the
       elements read at that location are logged to the 'pydicom'
       logger using python's logging module.
   
  -    :param debug_on: True (default) to turn on debugging,
  -    False to turn off.
  +    Parameters
  +    ----------
  +    debug_on : bool, optional
  +        If True (default) then turn on debugging, False to turn off.
  +    default_handler : bool, optional
  +        If True (default) then use ``logging.StreamHandler()`` as the handler
  +        for log messages.
       """
       global logger, debugging
  +
  +    if default_handler:
  +        handler = logging.StreamHandler()
  +        formatter = logging.Formatter("%(message)s")
  +        handler.setFormatter(formatter)
  +        logger.addHandler(handler)
  +
       if debug_on:
           logger.setLevel(logging.DEBUG)
           debugging = True
  @@ -129,4 +139,4 @@ def debug(debug_on=True):
   
   
   # force level=WARNING, in case logging default is set differently (issue 103)
  -debug(False)
  +debug(False, False)
   
  
file_context: {"pydicom/config.py": "# Copyright 2008-2018 pydicom authors. See LICENSE file for details.\n\"\"\"Pydicom configuration options.\"\"\"\n\n# doc strings following items are picked up by sphinx for documentation\n\nimport logging\n\n# Set the type used to hold DS values\n#    default False; was decimal-based in pydicom 0.9.7\nuse_DS_decimal = False\n\n\ndata_element_callback = None\n\"\"\"Set data_element_callback to a function to be called from read_dataset\nevery time a RawDataElement has been returned, before it is added\nto the dataset.\n\"\"\"\n\ndata_element_callback_kwargs = {}\n\"\"\"Set this to use as keyword arguments passed to the data_element_callback\nfunction\"\"\"\n\n\ndef reset_data_element_callback():\n    global data_element_callback\n    global data_element_callback_kwargs\n    data_element_callback = None\n    data_element_callback_kwargs = {}\n\n\ndef DS_decimal(use_Decimal_boolean=True):\n    \"\"\"Set DS class to be derived from Decimal (True) or from float (False)\n    If this function is never called, the default in pydicom >= 0.9.8\n    is for DS to be based on float.\n    \"\"\"\n    use_DS_decimal = use_Decimal_boolean\n    import pydicom.valuerep\n    if use_DS_decimal:\n        pydicom.valuerep.DSclass = pydicom.valuerep.DSdecimal\n    else:\n        pydicom.valuerep.DSclass = pydicom.valuerep.DSfloat\n\n\n# Configuration flags\nallow_DS_float = False\n\"\"\"Set allow_float to True to allow DSdecimal instances\nto be created with floats; otherwise, they must be explicitly\nconverted to strings, with the user explicity setting the\nprecision of digits and rounding. Default: False\"\"\"\n\nenforce_valid_values = False\n\"\"\"Raise errors if any value is not allowed by DICOM standard,\ne.g. DS strings that are longer than 16 characters;\nIS strings outside the allowed range.\n\"\"\"\n\ndatetime_conversion = False\n\"\"\"Set datetime_conversion to convert DA, DT and TM\ndata elements to datetime.date, datetime.datetime\nand datetime.time respectively. Default: False\n\"\"\"\n\n# Logging system and debug function to change logging level\nlogger = logging.getLogger('pydicom')\nhandler = logging.StreamHandler()\nformatter = logging.Formatter(\"%(message)s\")\nhandler.setFormatter(formatter)\nlogger.addHandler(handler)\n\n\nimport pydicom.pixel_data_handlers.numpy_handler as np_handler  # noqa\nimport pydicom.pixel_data_handlers.rle_handler as rle_handler  # noqa\nimport pydicom.pixel_data_handlers.pillow_handler as pillow_handler  # noqa\nimport pydicom.pixel_data_handlers.jpeg_ls_handler as jpegls_handler  # noqa\nimport pydicom.pixel_data_handlers.gdcm_handler as gdcm_handler  # noqa\n\npixel_data_handlers = [\n    np_handler,\n    rle_handler,\n    gdcm_handler,\n    pillow_handler,\n    jpegls_handler,\n]\n\"\"\"Handlers for converting (7fe0,0010) Pixel Data.\nThis is an ordered list that the dataset.convert_pixel_data()\nmethod will try to extract a correctly sized numpy array from the\nPixelData element.\n\nHanders shall have two methods:\n\ndef supports_transfer_syntax(ds)\n  This returns True if the handler might support the transfer syntax\n  indicated in the dicom_dataset\n\ndef get_pixeldata(ds):\n  This shall either throw an exception or return a correctly sized numpy\n  array derived from the PixelData.  Reshaping the array to the correct\n  dimensions is handled outside the image handler\n\nThe first handler that both announces that it supports the transfer syntax\nand does not throw an exception, either in getting the data or when the data\nis reshaped to the correct dimensions, is the handler that will provide the\ndata.\n\nIf they all fail, the last one to throw an exception gets to see its\nexception thrown up.\n\nIf no one throws an exception, but they all refuse to support the transfer\nsyntax, then this fact is announced in a NotImplementedError exception.\n\"\"\"\n\n\ndef debug(debug_on=True):\n    \"\"\"Turn debugging of DICOM file reading and writing on or off.\n    When debugging is on, file location and details about the\n    elements read at that location are logged to the 'pydicom'\n    logger using python's logging module.\n\n    :param debug_on: True (default) to turn on debugging,\n    False to turn off.\n    \"\"\"\n    global logger, debugging\n    if debug_on:\n        logger.setLevel(logging.DEBUG)\n        debugging = True\n    else:\n        logger.setLevel(logging.WARNING)\n        debugging = False\n\n\n# force level=WARNING, in case logging default is set differently (issue 103)\ndebug(False)\n"}
filelevel_patches: {"pydicom/config.py": "@@ -62,10 +62,7 @@ def DS_decimal(use_Decimal_boolean=True):\n \n # Logging system and debug function to change logging level\n logger = logging.getLogger('pydicom')\n-handler = logging.StreamHandler()\n-formatter = logging.Formatter(\"%(message)s\")\n-handler.setFormatter(formatter)\n-logger.addHandler(handler)\n+logger.addHandler(logging.NullHandler())\n \n \n import pydicom.pixel_data_handlers.numpy_handler as np_handler  # noqa\n@@ -110,16 +107,29 @@ def get_pixeldata(ds):\n \"\"\"\n \n \n-def debug(debug_on=True):\n-    \"\"\"Turn debugging of DICOM file reading and writing on or off.\n+def debug(debug_on=True, default_handler=True):\n+    \"\"\"Turn on/off debugging of DICOM file reading and writing.\n+\n     When debugging is on, file location and details about the\n     elements read at that location are logged to the 'pydicom'\n     logger using python's logging module.\n \n-    :param debug_on: True (default) to turn on debugging,\n-    False to turn off.\n+    Parameters\n+    ----------\n+    debug_on : bool, optional\n+        If True (default) then turn on debugging, False to turn off.\n+    default_handler : bool, optional\n+        If True (default) then use ``logging.StreamHandler()`` as the handler\n+        for log messages.\n     \"\"\"\n     global logger, debugging\n+\n+    if default_handler:\n+        handler = logging.StreamHandler()\n+        formatter = logging.Formatter(\"%(message)s\")\n+        handler.setFormatter(formatter)\n+        logger.addHandler(handler)\n+\n     if debug_on:\n         logger.setLevel(logging.DEBUG)\n         debugging = True\n@@ -129,4 +139,4 @@ def debug(debug_on=True):\n \n \n # force level=WARNING, in case logging default is set differently (issue 103)\n-debug(False)\n+debug(False, False)"}
messages.content: 
  We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  pydicom should not define handler, formatter and log level.
  The `config` module (imported when pydicom is imported) defines a handler and set the log level for the pydicom logger. This should not be the case IMO. It should be the responsibility of the client code of pydicom to configure the logging module to its convenience. Otherwise one end up having multiple logs record as soon as pydicom is imported:
  
  Example:
  ```
  Could not import pillow
  2018-03-25 15:27:29,744 :: DEBUG :: pydicom 
    Could not import pillow
  Could not import jpeg_ls
  2018-03-25 15:27:29,745 :: DEBUG :: pydicom 
    Could not import jpeg_ls
  Could not import gdcm
  2018-03-25 15:27:29,745 :: DEBUG :: pydicom 
    Could not import gdcm
  ``` 
  Or am I missing something?
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  
  --- BEGIN FILE ---
  ```
  ### pydicom/config.py
  # Copyright 2008-2018 pydicom authors. See LICENSE file for details.
  """Pydicom configuration options."""
  
  # doc strings following items are picked up by sphinx for documentation
  
  import logging
  
  # Set the type used to hold DS values
  #    default False; was decimal-based in pydicom 0.9.7
  use_DS_decimal = False
  
  
  data_element_callback = None
  """Set data_element_callback to a function to be called from read_dataset
  every time a RawDataElement has been returned, before it is added
  to the dataset.
  """
  
  data_element_callback_kwargs = {}
  """Set this to use as keyword arguments passed to the data_element_callback
  function"""
  
  
  def reset_data_element_callback():
      global data_element_callback
      global data_element_callback_kwargs
      data_element_callback = None
      data_element_callback_kwargs = {}
  
  
  def DS_decimal(use_Decimal_boolean=True):
      """Set DS class to be derived from Decimal (True) or from float (False)
      If this function is never called, the default in pydicom >= 0.9.8
      is for DS to be based on float.
      """
      use_DS_decimal = use_Decimal_boolean
      import pydicom.valuerep
      if use_DS_decimal:
          pydicom.valuerep.DSclass = pydicom.valuerep.DSdecimal
      else:
          pydicom.valuerep.DSclass = pydicom.valuerep.DSfloat
  
  
  # Configuration flags
  allow_DS_float = False
  """Set allow_float to True to allow DSdecimal instances
  to be created with floats; otherwise, they must be explicitly
  converted to strings, with the user explicity setting the
  precision of digits and rounding. Default: False"""
  
  enforce_valid_values = False
  """Raise errors if any value is not allowed by DICOM standard,
  e.g. DS strings that are longer than 16 characters;
  IS strings outside the allowed range.
  """
  
  datetime_conversion = False
  """Set datetime_conversion to convert DA, DT and TM
  data elements to datetime.date, datetime.datetime
  and datetime.time respectively. Default: False
  """
  
  # Logging system and debug function to change logging level
  logger = logging.getLogger('pydicom')
  handler = logging.StreamHandler()
  formatter = logging.Formatter("%(message)s")
  handler.setFormatter(formatter)
  logger.addHandler(handler)
  
  
  import pydicom.pixel_data_handlers.numpy_handler as np_handler  # noqa
  import pydicom.pixel_data_handlers.rle_handler as rle_handler  # noqa
  import pydicom.pixel_data_handlers.pillow_handler as pillow_handler  # noqa
  import pydicom.pixel_data_handlers.jpeg_ls_handler as jpegls_handler  # noqa
  import pydicom.pixel_data_handlers.gdcm_handler as gdcm_handler  # noqa
  
  pixel_data_handlers = [
      np_handler,
      rle_handler,
      gdcm_handler,
      pillow_handler,
      jpegls_handler,
  ]
  """Handlers for converting (7fe0,0010) Pixel Data.
  This is an ordered list that the dataset.convert_pixel_data()
  method will try to extract a correctly sized numpy array from the
  PixelData element.
  
  Handers shall have two methods:
  
  def supports_transfer_syntax(ds)
    This returns True if the handler might support the transfer syntax
    indicated in the dicom_dataset
  
  def get_pixeldata(ds):
    This shall either throw an exception or return a correctly sized numpy
    array derived from the PixelData.  Reshaping the array to the correct
    dimensions is handled outside the image handler
  
  The first handler that both announces that it supports the transfer syntax
  and does not throw an exception, either in getting the data or when the data
  is reshaped to the correct dimensions, is the handler that will provide the
  data.
  
  If they all fail, the last one to throw an exception gets to see its
  exception thrown up.
  
  If no one throws an exception, but they all refuse to support the transfer
  syntax, then this fact is announced in a NotImplementedError exception.
  """
  
  
  def debug(debug_on=True):
      """Turn debugging of DICOM file reading and writing on or off.
      When debugging is on, file location and details about the
      elements read at that location are logged to the 'pydicom'
      logger using python's logging module.
  
      :param debug_on: True (default) to turn on debugging,
      False to turn off.
      """
      global logger, debugging
      if debug_on:
          logger.setLevel(logging.DEBUG)
          debugging = True
      else:
          logger.setLevel(logging.WARNING)
          debugging = False
  
  
  # force level=WARNING, in case logging default is set differently (issue 103)
  debug(False)
  
  ```
  --- END FILE ---
  
  Please first localize the bug based on the issue statement, and then generate *SEARCH/REPLACE* edits to fix the issue.
  
  Every *SEARCH/REPLACE* edit must use this format:
  1. The file path
  2. The start of search block: <<<<<<< SEARCH
  3. A contiguous chunk of lines to search for in the existing source code
  4. The dividing line: =======
  5. The lines to replace into the source code
  6. The end of the replace block: >>>>>>> REPLACE
  
  Here is an example:
  
  ```python
  ### mathweb/flask/app.py
  <<<<<<< SEARCH
  from flask import Flask
  =======
  import math
  from flask import Flask
  >>>>>>> REPLACE
  ```
  
  Please note that the *SEARCH/REPLACE* edit REQUIRES PROPER INDENTATION. If you would like to add the line '        print(x)', you must fully write that out, with all those spaces before the code!
  Wrap the *SEARCH/REPLACE* edit in blocks ```python...```.
  
messages.role: user
verification_info: {"file_context": {"pydicom/config.py": "# Copyright 2008-2018 pydicom authors. See LICENSE file for details.\n\"\"\"Pydicom configuration options.\"\"\"\n\n# doc strings following items are picked up by sphinx for documentation\n\nimport logging\n\n# Set the type used to hold DS values\n#    default False; was decimal-based in pydicom 0.9.7\nuse_DS_decimal = False\n\n\ndata_element_callback = None\n\"\"\"Set data_element_callback to a function to be called from read_dataset\nevery time a RawDataElement has been returned, before it is added\nto the dataset.\n\"\"\"\n\ndata_element_callback_kwargs = {}\n\"\"\"Set this to use as keyword arguments passed to the data_element_callback\nfunction\"\"\"\n\n\ndef reset_data_element_callback():\n    global data_element_callback\n    global data_element_callback_kwargs\n    data_element_callback = None\n    data_element_callback_kwargs = {}\n\n\ndef DS_decimal(use_Decimal_boolean=True):\n    \"\"\"Set DS class to be derived from Decimal (True) or from float (False)\n    If this function is never called, the default in pydicom >= 0.9.8\n    is for DS to be based on float.\n    \"\"\"\n    use_DS_decimal = use_Decimal_boolean\n    import pydicom.valuerep\n    if use_DS_decimal:\n        pydicom.valuerep.DSclass = pydicom.valuerep.DSdecimal\n    else:\n        pydicom.valuerep.DSclass = pydicom.valuerep.DSfloat\n\n\n# Configuration flags\nallow_DS_float = False\n\"\"\"Set allow_float to True to allow DSdecimal instances\nto be created with floats; otherwise, they must be explicitly\nconverted to strings, with the user explicity setting the\nprecision of digits and rounding. Default: False\"\"\"\n\nenforce_valid_values = False\n\"\"\"Raise errors if any value is not allowed by DICOM standard,\ne.g. DS strings that are longer than 16 characters;\nIS strings outside the allowed range.\n\"\"\"\n\ndatetime_conversion = False\n\"\"\"Set datetime_conversion to convert DA, DT and TM\ndata elements to datetime.date, datetime.datetime\nand datetime.time respectively. Default: False\n\"\"\"\n\n# Logging system and debug function to change logging level\nlogger = logging.getLogger('pydicom')\nhandler = logging.StreamHandler()\nformatter = logging.Formatter(\"%(message)s\")\nhandler.setFormatter(formatter)\nlogger.addHandler(handler)\n\n\nimport pydicom.pixel_data_handlers.numpy_handler as np_handler  # noqa\nimport pydicom.pixel_data_handlers.rle_handler as rle_handler  # noqa\nimport pydicom.pixel_data_handlers.pillow_handler as pillow_handler  # noqa\nimport pydicom.pixel_data_handlers.jpeg_ls_handler as jpegls_handler  # noqa\nimport pydicom.pixel_data_handlers.gdcm_handler as gdcm_handler  # noqa\n\npixel_data_handlers = [\n    np_handler,\n    rle_handler,\n    gdcm_handler,\n    pillow_handler,\n    jpegls_handler,\n]\n\"\"\"Handlers for converting (7fe0,0010) Pixel Data.\nThis is an ordered list that the dataset.convert_pixel_data()\nmethod will try to extract a correctly sized numpy array from the\nPixelData element.\n\nHanders shall have two methods:\n\ndef supports_transfer_syntax(ds)\n  This returns True if the handler might support the transfer syntax\n  indicated in the dicom_dataset\n\ndef get_pixeldata(ds):\n  This shall either throw an exception or return a correctly sized numpy\n  array derived from the PixelData.  Reshaping the array to the correct\n  dimensions is handled outside the image handler\n\nThe first handler that both announces that it supports the transfer syntax\nand does not throw an exception, either in getting the data or when the data\nis reshaped to the correct dimensions, is the handler that will provide the\ndata.\n\nIf they all fail, the last one to throw an exception gets to see its\nexception thrown up.\n\nIf no one throws an exception, but they all refuse to support the transfer\nsyntax, then this fact is announced in a NotImplementedError exception.\n\"\"\"\n\n\ndef debug(debug_on=True):\n    \"\"\"Turn debugging of DICOM file reading and writing on or off.\n    When debugging is on, file location and details about the\n    elements read at that location are logged to the 'pydicom'\n    logger using python's logging module.\n\n    :param debug_on: True (default) to turn on debugging,\n    False to turn off.\n    \"\"\"\n    global logger, debugging\n    if debug_on:\n        logger.setLevel(logging.DEBUG)\n        debugging = True\n    else:\n        logger.setLevel(logging.WARNING)\n        debugging = False\n\n\n# force level=WARNING, in case logging default is set differently (issue 103)\ndebug(False)\n"}, "filelevel_patches": {"pydicom/config.py": "@@ -62,10 +62,7 @@ def DS_decimal(use_Decimal_boolean=True):\n \n # Logging system and debug function to change logging level\n logger = logging.getLogger('pydicom')\n-handler = logging.StreamHandler()\n-formatter = logging.Formatter(\"%(message)s\")\n-handler.setFormatter(formatter)\n-logger.addHandler(handler)\n+logger.addHandler(logging.NullHandler())\n \n \n import pydicom.pixel_data_handlers.numpy_handler as np_handler  # noqa\n@@ -110,16 +107,29 @@ def get_pixeldata(ds):\n \"\"\"\n \n \n-def debug(debug_on=True):\n-    \"\"\"Turn debugging of DICOM file reading and writing on or off.\n+def debug(debug_on=True, default_handler=True):\n+    \"\"\"Turn on/off debugging of DICOM file reading and writing.\n+\n     When debugging is on, file location and details about the\n     elements read at that location are logged to the 'pydicom'\n     logger using python's logging module.\n \n-    :param debug_on: True (default) to turn on debugging,\n-    False to turn off.\n+    Parameters\n+    ----------\n+    debug_on : bool, optional\n+        If True (default) then turn on debugging, False to turn off.\n+    default_handler : bool, optional\n+        If True (default) then use ``logging.StreamHandler()`` as the handler\n+        for log messages.\n     \"\"\"\n     global logger, debugging\n+\n+    if default_handler:\n+        handler = logging.StreamHandler()\n+        formatter = logging.Formatter(\"%(message)s\")\n+        handler.setFormatter(formatter)\n+        logger.addHandler(handler)\n+\n     if debug_on:\n         logger.setLevel(logging.DEBUG)\n         debugging = True\n@@ -129,4 +139,4 @@ def debug(debug_on=True):\n \n \n # force level=WARNING, in case logging default is set differently (issue 103)\n-debug(False)\n+debug(False, False)"}}