Repository: pydicom/pydicom

Issue:
missing directory dicomdirtests
<!-- Instructions For Filing a Bug: https://github.com/pydicom/pydicom/blob/master/CONTRIBUTING.md#filing-bugs -->

#### Description
A fresh clone and then `python setup.py install` triggers an error

#### Steps/Code to Reproduce

```
root@1cd9ed419b2f:/tmp# git clone https://github.com/pydicom/pydicom
Cloning into 'pydicom'...
remote: Counting objects: 6888, done.
remote: Compressing objects: 100% (15/15), done.
remote: Total 6888 (delta 0), reused 3 (delta 0), pack-reused 6873
Receiving objects: 100% (6888/6888), 15.33 MiB | 3.37 MiB/s, done.
Resolving deltas: 100% (3064/3064), done.
Checking connectivity... done.
root@1cd9ed419b2f:/tmp# cd pydicom
root@1cd9ed419b2f:/tmp/pydicom# python setup.py install
running install
running bdist_egg
running egg_info
creating pydicom.egg-info
writing dependency_links to pydicom.egg-info/dependency_links.txt
writing top-level names to pydicom.egg-info/top_level.txt
writing pydicom.egg-info/PKG-INFO
writing manifest file 'pydicom.egg-info/SOURCES.txt'
reading manifest file 'pydicom.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'pydicom.egg-info/SOURCES.txt'
installing library code to build/bdist.linux-x86_64/egg
running install_lib
running build_py
creating build
creating build/lib
creating build/lib/pydicom
copying pydicom/config.py -> build/lib/pydicom
copying pydicom/misc.py -> build/lib/pydicom
copying pydicom/filebase.py -> build/lib/pydicom
copying pydicom/__init__.py -> build/lib/pydicom
copying pydicom/dataelem.py -> build/lib/pydicom
copying pydicom/fileutil.py -> build/lib/pydicom
copying pydicom/filereader.py -> build/lib/pydicom
copying pydicom/dicomio.py -> build/lib/pydicom
copying pydicom/filewriter.py -> build/lib/pydicom
copying pydicom/multival.py -> build/lib/pydicom
copying pydicom/errors.py -> build/lib/pydicom
copying pydicom/_dicom_dict.py -> build/lib/pydicom
copying pydicom/valuerep.py -> build/lib/pydicom
copying pydicom/_version.py -> build/lib/pydicom
copying pydicom/charset.py -> build/lib/pydicom
copying pydicom/tag.py -> build/lib/pydicom
copying pydicom/_storage_sopclass_uids.py -> build/lib/pydicom
copying pydicom/values.py -> build/lib/pydicom
copying pydicom/uid.py -> build/lib/pydicom
copying pydicom/compat.py -> build/lib/pydicom
copying pydicom/_uid_dict.py -> build/lib/pydicom
copying pydicom/_private_dict.py -> build/lib/pydicom
copying pydicom/sequence.py -> build/lib/pydicom
copying pydicom/datadict.py -> build/lib/pydicom
copying pydicom/encaps.py -> build/lib/pydicom
copying pydicom/tagtools.py -> build/lib/pydicom
copying pydicom/dataset.py -> build/lib/pydicom
copying pydicom/dicomdir.py -> build/lib/pydicom
creating build/lib/pydicom/util
copying pydicom/util/__init__.py -> build/lib/pydicom/util
copying pydicom/util/codify.py -> build/lib/pydicom/util
copying pydicom/util/hexutil.py -> build/lib/pydicom/util
copying pydicom/util/fixer.py -> build/lib/pydicom/util
copying pydicom/util/leanread.py -> build/lib/pydicom/util
copying pydicom/util/dump.py -> build/lib/pydicom/util
creating build/lib/pydicom/tests
copying pydicom/tests/test_dictionary.py -> build/lib/pydicom/tests
copying pydicom/tests/_write_stds.py -> build/lib/pydicom/tests
copying pydicom/tests/__init__.py -> build/lib/pydicom/tests
copying pydicom/tests/test_tag.py -> build/lib/pydicom/tests
copying pydicom/tests/test_util.py -> build/lib/pydicom/tests
copying pydicom/tests/test_filewriter.py -> build/lib/pydicom/tests
copying pydicom/tests/test_uid.py -> build/lib/pydicom/tests
copying pydicom/tests/test_valuerep.py -> build/lib/pydicom/tests
copying pydicom/tests/test_misc.py -> build/lib/pydicom/tests
copying pydicom/tests/test_charset.py -> build/lib/pydicom/tests
copying pydicom/tests/test_sequence.py -> build/lib/pydicom/tests
copying pydicom/tests/test_rawread.py -> build/lib/pydicom/tests
copying pydicom/tests/test_dataset.py -> build/lib/pydicom/tests
copying pydicom/tests/test_unicode.py -> build/lib/pydicom/tests
copying pydicom/tests/test_dataelem.py -> build/lib/pydicom/tests
copying pydicom/tests/test_multival.py -> build/lib/pydicom/tests
copying pydicom/tests/test_filereader.py -> build/lib/pydicom/tests
creating build/lib/pydicom/contrib
copying pydicom/contrib/__init__.py -> build/lib/pydicom/contrib
copying pydicom/contrib/pydicom_PIL.py -> build/lib/pydicom/contrib
copying pydicom/contrib/dicom_dao.py -> build/lib/pydicom/contrib
copying pydicom/contrib/pydicom_Tkinter.py -> build/lib/pydicom/contrib
copying pydicom/contrib/dcm_qt_tree.py -> build/lib/pydicom/contrib
copying pydicom/contrib/imViewer_Simple.py -> build/lib/pydicom/contrib
copying pydicom/contrib/pydicom_series.py -> build/lib/pydicom/contrib
creating build/lib/pydicom/util/testing
copying pydicom/util/testing/_write_stds.py -> build/lib/pydicom/util/testing
copying pydicom/util/testing/__init__.py -> build/lib/pydicom/util/testing
copying pydicom/util/testing/warncheck.py -> build/lib/pydicom/util/testing
copying pydicom/util/testing/version_dep.py -> build/lib/pydicom/util/testing
creating build/lib/pydicom/tests/performance
copying pydicom/tests/performance/__init__.py -> build/lib/pydicom/tests/performance
copying pydicom/tests/performance/raw_convert_test.py -> build/lib/pydicom/tests/performance
copying pydicom/tests/performance/time_test.py -> build/lib/pydicom/tests/performance
copying pydicom/README.txt -> build/lib/pydicom
creating build/lib/pydicom/tests/test_files
copying pydicom/tests/test_files/rtstruct.dcm -> build/lib/pydicom/tests/test_files
copying pydicom/tests/test_files/no_meta_group_length.dcm -> build/lib/pydicom/tests/test_files
copying pydicom/tests/test_files/MR_small.dcm -> build/lib/pydicom/tests/test_files
copying pydicom/tests/test_files/MR_small_jp2klossless.dcm -> build/lib/pydicom/tests/test_files
copying pydicom/tests/test_files/color-px.dcm -> build/lib/pydicom/tests/test_files
copying pydicom/tests/test_files/color3d_jpeg_baseline.dcm -> build/lib/pydicom/tests/test_files
copying pydicom/tests/test_files/nested_priv_SQ.dcm -> build/lib/pydicom/tests/test_files
copying pydicom/tests/test_files/rtplan.dcm -> build/lib/pydicom/tests/test_files
copying pydicom/tests/test_files/reportsi_with_empty_number_tags.dcm -> build/lib/pydicom/tests/test_files
copying pydicom/tests/test_files/reportsi.dcm -> build/lib/pydicom/tests/test_files
copying pydicom/tests/test_files/CT_small.dcm -> build/lib/pydicom/tests/test_files
copying pydicom/tests/test_files/rtplan.dump -> build/lib/pydicom/tests/test_files
copying pydicom/tests/test_files/emri_small_big_endian.dcm -> build/lib/pydicom/tests/test_files
copying pydicom/tests/test_files/ExplVR_LitEndNoMeta.dcm -> build/lib/pydicom/tests/test_files
copying pydicom/tests/test_files/test-SR.dcm -> build/lib/pydicom/tests/test_files
copying pydicom/tests/test_files/JPEG2000.dcm -> build/lib/pydicom/tests/test_files
copying pydicom/tests/test_files/JPEG-lossy.dcm -> build/lib/pydicom/tests/test_files
copying pydicom/tests/test_files/MR_small_jpeg_ls_lossless.dcm -> build/lib/pydicom/tests/test_files
copying pydicom/tests/test_files/rtstruct.dump -> build/lib/pydicom/tests/test_files
copying pydicom/tests/test_files/color-pl.dcm -> build/lib/pydicom/tests/test_files
copying pydicom/tests/test_files/ExplVR_BigEnd.dcm -> build/lib/pydicom/tests/test_files
copying pydicom/tests/test_files/emri_small_jpeg_ls_lossless.dcm -> build/lib/pydicom/tests/test_files
copying pydicom/tests/test_files/JPEG-LL.dcm -> build/lib/pydicom/tests/test_files
error: can't copy 'pydicom/tests/test_files/dicomdirtests': doesn't exist or not a regular file
```
search for dicomdirtests...
```
root@1cd9ed419b2f:/tmp/pydicom# grep -R dicomdirtests
pydicom/tests/test_files/README.txt:dicomdirtests files were from http://www.pcir.org, freely available image sets.
pydicom/tests/test_files/README.txt:straight read of the dicomdirtests DICOMDIR file. The DICOMDIR file itself
release-checklist.txt:    cd ..\..\tests\test_files\dicomdirtests
Binary file .git/index matches
```


#### Expected Results
pydicom is installed without missing error

#### Actual Results
```
error: can't copy 'pydicom/tests/test_files/dicomdirtests': doesn't exist or not a regular file
```

#### Versions
```
>>> import platform; print(platform.platform())
Linux-4.4.0-83-generic-x86_64-with-debian-8.4
>>> import sys; print("Python", sys.version)
Python 3.5.1 (default, Jun  9 2016, 15:37:54) 
[GCC 4.9.2]
>>> import pydicom; print("pydicom", pydicom.__version__)
pydicom 1.0.0a1
```

Discussion:
glemaitre: I don't see why to edit data_files since the file are closely related to the package, aren't they?
I am -1 for that one.

https://docs.python.org/2/distutils/setupscript.html#installing-package-data

mrbean-bremen: Well, that is a matter of viewpoint. It doesn't make much difference, though, so as the test files are indeed inside the package it may make sense to use `package_data` for that (I first thought that they need an `__init__.py` in the subdirectories, but I mis-remembered that). 
Anyway, in this case the code has to be only slightly altered to use `PACKAGE_DATA` instead of `DATA_FILES`.
pep8speaks: Hello @vsoch! Thanks for updating the PR.

 - In the file [`setup.py`](https://github.com/pydicom/pydicom/blob/b1d5bdaea91c218ffe221b8b9ebfdb7593e38d5d/setup.py), following are the PEP8 issues :

> [Line 63:38](https://github.com/pydicom/pydicom/blob/b1d5bdaea91c218ffe221b8b9ebfdb7593e38d5d/setup.py#L63): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ','
> [Line 64:17](https://github.com/pydicom/pydicom/blob/b1d5bdaea91c218ffe221b8b9ebfdb7593e38d5d/setup.py#L64): [E128](https://duckduckgo.com/?q=pep8%20E128) continuation line under-indented for visual indent
> [Line 65:40](https://github.com/pydicom/pydicom/blob/b1d5bdaea91c218ffe221b8b9ebfdb7593e38d5d/setup.py#L65): [W291](https://duckduckgo.com/?q=pep8%20W291) trailing whitespace


glemaitre: @vsoch what do you think about putting everything into a function `data_file_inventory()` which will grab everything and then call `PACKAGE_DATE = {'pydicom': data_file_inventory()}. It avoids a constant variable knowing that DATA_FILES is also a keyword in setup.py which can be confusing at some point.
mrbean-bremen: You could also add the root path as argument to the function, and call it then with the two test file directories. This would only add the test files, not the tests themselves.
vsoch: The idea I like most is a combination of what you both suggested - having a general function to return an inventory of files, but then I would want to reorganize them (with the function) under some `pydicom/data` folder. So then it would be like:

```
pydicom
    data/
      __init__.py   <--- data_files_inventory
```
and in the setup, we would move variables and functions to some internal package `version.py` that would do the relative import for the data files inventory:

```
from .data import data_files_inventory
```

and then define the PACKAGE_DATA as we do now (and maybe giving a path?):

```
PACKAGE_DATA = {"pydicom":data_files_inventory('pydicom/tests')}
```

And that way, given that we have some logical organization of files under data, for example:

```
/data
   group1/
   group2
```

The user could take advantage of the function too, like:

```
from pydicom.data import data_files_inventory
group1_files = data_files_inventory('group1')
```
Either the path could be relative to the root, or to data files folder.
vsoch: but I think #427 would also be dependency here, if there are data files within tests, we would want to figure out that organization first!
glemaitre: @vsoch I like your proposition. +1
massich: huge kudos to this:
> but I think #427 would also be dependency here, if there are data files within tests, we would want to figure out that organization first!

And we should also figure out which ones. From #427 see:
> ￼ Use data from examples (see discussion in #404) (blocked by migrating the examples back)

So I think we'll iterate over it. So propose some initial structure and then we'll take it from there. 
vsoch: this is going to have a huuge number of pep8 errors (because I had to modify some test files) but we can deal with as necessary.
glemaitre: Use yapf to correct the majority of them and go by hand for the remianing
massich: > this is going to have a huuge number of pep8 errors (because I had to modify some test files) but we can deal with as necessary.
The best way I found is to use `yapf -i /path/filename.py` and then use a **diff** tool to inspect the changes and fine tune it. 
vsoch: Here is basic usage:

https://asciinema.org/a/130586?speed=3
glemaitre: @vsoch The next step is to move those file in a `testdata` subpackage and write fetcher instead of a unique function in `__init__.py` which will not be tested ;D

@massich knows couple of things about those fetcher due to recent annoying scikit-learn PR ;)
vsoch: so now the question is:

 - what paths need to be included in setup.py, if any?
 - what goes in setup.py vs. recursive-include in MANIFEST.in?

It looks like I can completely remove the bit in the setup.py, and then I miss some of the deeper folders in charset_files that don't have an __init__.py (but the package installs correctly). Otherwise, we can either leave as is with a function to find all files, or specify specific paths (if only a few). 
vsoch: @glemaitre could you break this apart into a little more detail?

>> @vsoch The next step is to move those file in a testdata subpackage and write fetcher instead of a unique function in __init__.py which will not be tested ;D

- subpackage means another module under data, isn't that akin to data/test?
- what is the difference between a function get_dataset and a fetcher?
glemaitre: refer to https://github.com/scikit-learn/scikit-learn/tree/master/sklearn/datasets
and
http://scikit-learn.org/stable/modules/classes.html#module-sklearn.datasets

In this case you can load easily during unit testing and for the example and user guide.
glemaitre: > what paths need to be included in setup.py, if any?

not sure what you mean by path. you still need the package_data as before

> what goes in setup.py vs. recursive-include in MANIFEST.in?

you need to repeat it because MANIFEST.in is used for tarball generation while setup.py is used for the install.

> It looks like I can completely remove the bit in the setup.py, and then I miss some of the deeper folders in charset_files that don't have an init.py (but the package installs correctly). Otherwise, we can either leave as is with a function to find all files, or specify specific paths (if only a few).

I would put an `__init__.py` everywhere otherwise the `find_package` from setuptools can get into trouble sometimes.
glemaitre: > what is the difference between a function get_dataset and a fetcher?

I just want a module and not a function in an __init__.py  and a `tests/test_soemthing.py` that goes with it.
vsoch: How would you want it to work? The links you sent seem like a really robust / complicated setup - I wonder if we could do something simpler until we need something more complicated?
glemaitre: Oh I missed that the data moved to `data`. I would add one level as in scikit-learn.

massich: When I said
> So propose some initial structure and then we'll take it from there.

It was to no start with the fetcher yet ;) I think that before start to stripping data out I think we need (or at least I need) to go through the examples and tests. To see which part could be shipped embedded with the package as basic data to test and which data could be downloaded through the fetcher when needed. Meanwhile, this would give me the time to build the second version of sci-kit learn's fetcher and then I'll adapt the code once I had gone through the examples. 
massich: @vsoch all that basic usage you were referring to I wanted to place it in `pydicom/datsets/base.py`.  The problem is that directory dataset is not a good naming (see #388 ). My idea in #426: 
> Attempts to review some part of the testsuit. Particularly, factorizes how the test data is retrieved.

was exactly this one. Workout the tests to call the testing data in a uniformed manner and then write the part of the package in charge to fulfill such tests.



mrbean-bremen: I agree with @vsoch here - maybe you just try to solve the problem at hand in a simple way, before going to the complicated solution. Looks a little overengineered to me for this, but I  may be wrong. 
glemaitre: > Looks a little overengineered to me for this, but I may be wrong.

What is imperatively needed is a unit test for you function.
massich: I think we need to iterate. So I would go for whatever solution keeps the CI's and setups happy. Touching as little code as possible. Then refactor tests, analyze how much data do we actually need to test what, create testdata generators if needed, find nice documented dicoms to illustrate the cases and then go for the fetcher.  
massich: IMHO tasks to finish this PR:
- [ ] ensure PEP8 does not scream
- [ ] move the code from `data/__init__.py` to `data/base.py` (see *)
- [ ] unit test EVERYTHING

* In this manner the calls end up like this:
```py
from pydicom.data import get_datadir

bla bla bla
```

massich: And BTW, this is blocking #426. Which is perfectly fine.
vsoch: @massich the calls already work like that. But you are saying you want functions outside of the init?
vsoch: I like the plan of action, but "clean up the commits history" seems like overkill. 
glemaitre: We will able to squash at merging 
massich: @vsoch 
> But you are saying you want functions outside of the init?

yes. Its much more convenient in the long run. First 'cos I encloses all the helper functions in `data.base` and second 'cos an `__init__.py` full of stuff can be difficult to work with and can be loaded in a wired manner (I think)
vsoch: oh that's a very good point! I've been on a "put it in the __init__" spree after figuring out how nice it was to organize things in a module (via different scripts) and then have available via the folder name as a module. Those use cases were for django modules though, when I'd want all of the things to load at start of the application. This is definitely different! Let me see what I can come up with.
vsoch: okay, read to go I think. The only issue that pep8 didn't like that I need some help with (to not do it wrong) was with the lambda in test_dataset.py for TestTagExceptionWalk:

```
        callback = lambda dataset, data_element: str(data_element)
        func = lambda: ds.walk(callback)
```
rhaxton: In PR#409, I  changed those lines from

```
         callback = lambda dataset, data_element: str(data_element)
         func = lambda: ds.walk(callback)
```
to
```
        def callback(dataset, data_element):
            return str(data_element)

        def func(dataset=ds):
            return dataset.walk(callback)
```
to make @pep8speaks give me a "cheers!"

vsoch: thanks - I'm on it! I want a :cheese: too (they didn't have cheer, so that's the best I could do :P)
vsoch: @pep8speaks hello status report!
vsoch: okay, now I think we are ready for another look! pep8speaks has redeemed me so I can die happy now.
massich: @vsoch what happen to this PR? We need this PR it was a great job!
vsoch: After 70+ comments and not producing something satisfactory, and merge of https://github.com/pydicom/pydicom/commit/ddbc86080ee1e7fe6845dbfe05a4e10d6e54fa7a that would require doing the work over anyway, the PR ran away.
vsoch: but if you are candid that it was wanted, it will definitely come back :)
vsoch: it looks like travis tests are failing for gdcm for when gdcm = true:

![image](https://user-images.githubusercontent.com/814322/28791373-10ab2110-75e1-11e7-813e-2f793f87f18b.png)

vsoch: looks like it was found in the last successful build:

![image](https://user-images.githubusercontent.com/814322/28791843-8e4953e8-75e2-11e7-980f-5d168d817593.png)

mrbean-bremen: Yes - it started to fail in the middle of handling #443, did find GDCM in the tests for 2.7 and 3.4, but didn't in all later tests. I guess something has changed in their build enviroment, or in one of the package sources.
Maybe we can try to use Precise instead of Trusty...
mrbean-bremen: Ok, reverting to precise works, at least as a temporary solution.
vsoch: ok, I'm trying anaconda with trusty, then precise with miniconda. If these things fail, then we can debug by looking at the configuration settings for conda, and go from there. The install works on my local machine, so minimally if we find differences between the two in the install process it might help. There were a few issues on Github that had things like an outdated requests/urllib3 not working for conda-forge, so likely it's something weird like that.
vsoch: I got it down to just one set of tests failing - pypy for python 3.5, and it's because of permissions with wheels. I'm going to try disabling the cache, then changing directory permissions. I don't know what the deal is with wheels, but they have caused much pain across many of the projects I work on, lol.
glemaitre: ouch I was a bit slow. 

Be careful, you are not using gdcm in the test environment:
https://travis-ci.org/pydicom/pydicom/jobs/259541625#L634
It was strange to me that installing a binary of python 3.5 was working in python 2.7 ;)

I did not check yet but are you sure that conda remote is not down or something like that?
I'll try to check what's happening.
vsoch: sounds good. I'm still going to bask a little in the green, this PR has taken a toll!
vsoch: @darcymason I believe the remaining bug was figuring out the gdcm issue, but I think that is separate from the data module. I'd hope we can merge this before getting to 100 comments!
glemaitre: @pydicom/pydcom-fff 

So the issue with the CI is upstream with the conda and conda channels. Other packages reported the same error as pandas: https://github.com/conda/conda/issues/5761

I reported an error in conda-forge: https://github.com/conda-forge/conda-forge.github.io/issues/419
and it seems that it is coming from anaconda: https://github.com/Anaconda-Platform/support/issues/126

I would suggest to revert all the CI back to the original setup and wait for a resolution upstream.
vsoch: yep did that last night, the install.sh file is in sync with that in master.
vsoch: The world shook a little yesterday - Github was off an on (something about moving to Kubernetes?) And conda was definitely (and might still be off). Reproducible science at best was home with a fever, if not questioning its self worth!
glemaitre: I think that you need to revert `.travis.yml` and `build_tools/travis/install.sh`. We will make a PR to solve the issue pointed by @rhaxton regarding the install of some library.

The IP of travis was blocked by conda. It is solved now so you can relaunch a build and I think that we should be MRG+1 on my side.
glemaitre: @pydicom/pydicom-core MRG+2 on our side
vsoch: :D 

Patch:
diff --git a/pydicom/data/__init__.py b/pydicom/data/__init__.py
new file mode 100644
index 000000000..c1c542e0b
--- /dev/null
+++ b/pydicom/data/__init__.py
@@ -0,0 +1,12 @@
+"""pydicom data manager"""
+#
+# Copyright (c) 2008-2012 Darcy Mason
+# Copyright (c) 2017 pydicom AUTHORS
+# This file is part of pydicom, released under a modified MIT license.
+#    See the file LICENSE included with this distribution, also
+#    available at https://github.com/pydicom/pydicom
+#
+
+from .base import (get_charset_files,
+                   get_testdata_files,
+                   DATA_ROOT)
diff --git a/pydicom/data/base.py b/pydicom/data/base.py
new file mode 100644
index 000000000..5fc7b3cdf
--- /dev/null
+++ b/pydicom/data/base.py
@@ -0,0 +1,50 @@
+"""pydicom data manager"""
+#
+# Copyright (c) 2008-2012 Darcy Mason
+# Copyright (c) 2017 pydicom AUTHORS
+# This file is part of pydicom, released under a modified MIT license.
+#    See the file LICENSE included with this distribution, also
+#    available at https://github.com/pydicom/pydicom
+#
+
+from os.path import abspath, dirname, join
+from .utils import get_files
+
+
+DATA_ROOT = abspath(dirname(__file__))
+
+
+def get_testdata_files(pattern="*"):
+    """Return test data files from pydicom data root
+
+    Parameters
+    ----------
+    pattern : string
+            A string pattern to filter the files
+
+    Returns
+    ----------
+    files : list of test data files
+
+    """
+
+    data_path = join(DATA_ROOT, 'test_files')
+    return get_files(bases=data_path, pattern=pattern)
+
+
+def get_charset_files(pattern="*"):
+    """Return charset files from pydicom data root
+
+    Parameters
+    ----------
+    pattern : string
+            A string pattern to filter the files
+
+    Returns
+    ----------
+    files : list of charset data files
+
+    """
+
+    data_path = join(DATA_ROOT, 'charset_files')
+    return get_files(bases=data_path, pattern=pattern)
diff --git a/pydicom/tests/charset_files/FileInfo.txt b/pydicom/data/charset_files/FileInfo.txt
similarity index 100%
rename from pydicom/tests/charset_files/FileInfo.txt
rename to pydicom/data/charset_files/FileInfo.txt
diff --git a/pydicom/data/charset_files/__init__.py b/pydicom/data/charset_files/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/pydicom/tests/charset_files/charlist.py b/pydicom/data/charset_files/charlist.py
similarity index 100%
rename from pydicom/tests/charset_files/charlist.py
rename to pydicom/data/charset_files/charlist.py
diff --git a/pydicom/tests/charset_files/chrArab.dcm b/pydicom/data/charset_files/chrArab.dcm
similarity index 100%
rename from pydicom/tests/charset_files/chrArab.dcm
rename to pydicom/data/charset_files/chrArab.dcm
diff --git a/pydicom/tests/charset_files/chrFren.dcm b/pydicom/data/charset_files/chrFren.dcm
similarity index 100%
rename from pydicom/tests/charset_files/chrFren.dcm
rename to pydicom/data/charset_files/chrFren.dcm
diff --git a/pydicom/tests/charset_files/chrFrenMulti.dcm b/pydicom/data/charset_files/chrFrenMulti.dcm
similarity index 100%
rename from pydicom/tests/charset_files/chrFrenMulti.dcm
rename to pydicom/data/charset_files/chrFrenMulti.dcm
diff --git a/pydicom/tests/charset_files/chrGerm.dcm b/pydicom/data/charset_files/chrGerm.dcm
similarity index 100%
rename from pydicom/tests/charset_files/chrGerm.dcm
rename to pydicom/data/charset_files/chrGerm.dcm
diff --git a/pydicom/tests/charset_files/chrGreek.dcm b/pydicom/data/charset_files/chrGreek.dcm
similarity index 100%
rename from pydicom/tests/charset_files/chrGreek.dcm
rename to pydicom/data/charset_files/chrGreek.dcm
diff --git a/pydicom/tests/charset_files/chrH31.dcm b/pydicom/data/charset_files/chrH31.dcm
similarity index 100%
rename from pydicom/tests/charset_files/chrH31.dcm
rename to pydicom/data/charset_files/chrH31.dcm
diff --git a/pydicom/tests/charset_files/chrH32.dcm b/pydicom/data/charset_files/chrH32.dcm
similarity index 100%
rename from pydicom/tests/charset_files/chrH32.dcm
rename to pydicom/data/charset_files/chrH32.dcm
diff --git a/pydicom/tests/charset_files/chrHbrw.dcm b/pydicom/data/charset_files/chrHbrw.dcm
similarity index 100%
rename from pydicom/tests/charset_files/chrHbrw.dcm
rename to pydicom/data/charset_files/chrHbrw.dcm
diff --git a/pydicom/tests/charset_files/chrI2.dcm b/pydicom/data/charset_files/chrI2.dcm
similarity index 100%
rename from pydicom/tests/charset_files/chrI2.dcm
rename to pydicom/data/charset_files/chrI2.dcm
diff --git a/pydicom/tests/charset_files/chrJapMulti.dcm b/pydicom/data/charset_files/chrJapMulti.dcm
similarity index 100%
rename from pydicom/tests/charset_files/chrJapMulti.dcm
rename to pydicom/data/charset_files/chrJapMulti.dcm
diff --git a/pydicom/tests/charset_files/chrJapMultiExplicitIR6.dcm b/pydicom/data/charset_files/chrJapMultiExplicitIR6.dcm
similarity index 100%
rename from pydicom/tests/charset_files/chrJapMultiExplicitIR6.dcm
rename to pydicom/data/charset_files/chrJapMultiExplicitIR6.dcm
diff --git a/pydicom/tests/charset_files/chrKoreanMulti.dcm b/pydicom/data/charset_files/chrKoreanMulti.dcm
similarity index 100%
rename from pydicom/tests/charset_files/chrKoreanMulti.dcm
rename to pydicom/data/charset_files/chrKoreanMulti.dcm
diff --git a/pydicom/tests/charset_files/chrRuss.dcm b/pydicom/data/charset_files/chrRuss.dcm
similarity index 100%
rename from pydicom/tests/charset_files/chrRuss.dcm
rename to pydicom/data/charset_files/chrRuss.dcm
diff --git a/pydicom/tests/charset_files/chrSQEncoding.dcm b/pydicom/data/charset_files/chrSQEncoding.dcm
similarity index 100%
rename from pydicom/tests/charset_files/chrSQEncoding.dcm
rename to pydicom/data/charset_files/chrSQEncoding.dcm
diff --git a/pydicom/tests/charset_files/chrX1.dcm b/pydicom/data/charset_files/chrX1.dcm
similarity index 100%
rename from pydicom/tests/charset_files/chrX1.dcm
rename to pydicom/data/charset_files/chrX1.dcm
diff --git a/pydicom/tests/charset_files/chrX2.dcm b/pydicom/data/charset_files/chrX2.dcm
similarity index 100%
rename from pydicom/tests/charset_files/chrX2.dcm
rename to pydicom/data/charset_files/chrX2.dcm
diff --git a/pydicom/tests/test_files/CT_small.dcm b/pydicom/data/test_files/CT_small.dcm
similarity index 100%
rename from pydicom/tests/test_files/CT_small.dcm
rename to pydicom/data/test_files/CT_small.dcm
diff --git a/pydicom/tests/test_files/ExplVR_BigEnd.dcm b/pydicom/data/test_files/ExplVR_BigEnd.dcm
similarity index 100%
rename from pydicom/tests/test_files/ExplVR_BigEnd.dcm
rename to pydicom/data/test_files/ExplVR_BigEnd.dcm
diff --git a/pydicom/tests/test_files/ExplVR_BigEndNoMeta.dcm b/pydicom/data/test_files/ExplVR_BigEndNoMeta.dcm
similarity index 100%
rename from pydicom/tests/test_files/ExplVR_BigEndNoMeta.dcm
rename to pydicom/data/test_files/ExplVR_BigEndNoMeta.dcm
diff --git a/pydicom/tests/test_files/ExplVR_LitEndNoMeta.dcm b/pydicom/data/test_files/ExplVR_LitEndNoMeta.dcm
similarity index 100%
rename from pydicom/tests/test_files/ExplVR_LitEndNoMeta.dcm
rename to pydicom/data/test_files/ExplVR_LitEndNoMeta.dcm
diff --git a/pydicom/tests/test_files/JPEG-LL.dcm b/pydicom/data/test_files/JPEG-LL.dcm
similarity index 100%
rename from pydicom/tests/test_files/JPEG-LL.dcm
rename to pydicom/data/test_files/JPEG-LL.dcm
diff --git a/pydicom/tests/test_files/JPEG-lossy.dcm b/pydicom/data/test_files/JPEG-lossy.dcm
similarity index 100%
rename from pydicom/tests/test_files/JPEG-lossy.dcm
rename to pydicom/data/test_files/JPEG-lossy.dcm
diff --git a/pydicom/tests/test_files/JPEG2000.dcm b/pydicom/data/test_files/JPEG2000.dcm
similarity index 100%
rename from pydicom/tests/test_files/JPEG2000.dcm
rename to pydicom/data/test_files/JPEG2000.dcm
diff --git a/pydicom/tests/test_files/MR_small.dcm b/pydicom/data/test_files/MR_small.dcm
similarity index 100%
rename from pydicom/tests/test_files/MR_small.dcm
rename to pydicom/data/test_files/MR_small.dcm
diff --git a/pydicom/tests/test_files/MR_small_RLE.dcm b/pydicom/data/test_files/MR_small_RLE.dcm
similarity index 100%
rename from pydicom/tests/test_files/MR_small_RLE.dcm
rename to pydicom/data/test_files/MR_small_RLE.dcm
diff --git a/pydicom/tests/test_files/MR_small_jp2klossless.dcm b/pydicom/data/test_files/MR_small_jp2klossless.dcm
similarity index 100%
rename from pydicom/tests/test_files/MR_small_jp2klossless.dcm
rename to pydicom/data/test_files/MR_small_jp2klossless.dcm
diff --git a/pydicom/tests/test_files/MR_small_jpeg_ls_lossless.dcm b/pydicom/data/test_files/MR_small_jpeg_ls_lossless.dcm
similarity index 100%
rename from pydicom/tests/test_files/MR_small_jpeg_ls_lossless.dcm
rename to pydicom/data/test_files/MR_small_jpeg_ls_lossless.dcm
diff --git a/pydicom/tests/test_files/MR_truncated.dcm b/pydicom/data/test_files/MR_truncated.dcm
similarity index 100%
rename from pydicom/tests/test_files/MR_truncated.dcm
rename to pydicom/data/test_files/MR_truncated.dcm
diff --git a/pydicom/tests/test_files/OBXXXX1A.dcm b/pydicom/data/test_files/OBXXXX1A.dcm
similarity index 100%
rename from pydicom/tests/test_files/OBXXXX1A.dcm
rename to pydicom/data/test_files/OBXXXX1A.dcm
diff --git a/pydicom/tests/test_files/OT-PAL-8-face.dcm b/pydicom/data/test_files/OT-PAL-8-face.dcm
similarity index 100%
rename from pydicom/tests/test_files/OT-PAL-8-face.dcm
rename to pydicom/data/test_files/OT-PAL-8-face.dcm
diff --git a/pydicom/tests/test_files/README.txt b/pydicom/data/test_files/README.txt
similarity index 100%
rename from pydicom/tests/test_files/README.txt
rename to pydicom/data/test_files/README.txt
diff --git a/pydicom/data/test_files/__init__.py b/pydicom/data/test_files/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/pydicom/tests/test_files/badVR.dcm b/pydicom/data/test_files/badVR.dcm
similarity index 100%
rename from pydicom/tests/test_files/badVR.dcm
rename to pydicom/data/test_files/badVR.dcm
diff --git a/pydicom/tests/test_files/color-pl.dcm b/pydicom/data/test_files/color-pl.dcm
similarity index 100%
rename from pydicom/tests/test_files/color-pl.dcm
rename to pydicom/data/test_files/color-pl.dcm
diff --git a/pydicom/tests/test_files/color-px.dcm b/pydicom/data/test_files/color-px.dcm
similarity index 100%
rename from pydicom/tests/test_files/color-px.dcm
rename to pydicom/data/test_files/color-px.dcm
diff --git a/pydicom/tests/test_files/color3d_jpeg_baseline.dcm b/pydicom/data/test_files/color3d_jpeg_baseline.dcm
similarity index 100%
rename from pydicom/tests/test_files/color3d_jpeg_baseline.dcm
rename to pydicom/data/test_files/color3d_jpeg_baseline.dcm
diff --git a/pydicom/tests/test_files/dicomdirtests/77654033/CR1/6154 b/pydicom/data/test_files/dicomdirtests/77654033/CR1/6154
similarity index 100%
rename from pydicom/tests/test_files/dicomdirtests/77654033/CR1/6154
rename to pydicom/data/test_files/dicomdirtests/77654033/CR1/6154
diff --git a/pydicom/tests/test_files/dicomdirtests/77654033/CR2/6247 b/pydicom/data/test_files/dicomdirtests/77654033/CR2/6247
similarity index 100%
rename from pydicom/tests/test_files/dicomdirtests/77654033/CR2/6247
rename to pydicom/data/test_files/dicomdirtests/77654033/CR2/6247
diff --git a/pydicom/tests/test_files/dicomdirtests/77654033/CR3/6278 b/pydicom/data/test_files/dicomdirtests/77654033/CR3/6278
similarity index 100%
rename from pydicom/tests/test_files/dicomdirtests/77654033/CR3/6278
rename to pydicom/data/test_files/dicomdirtests/77654033/CR3/6278
diff --git a/pydicom/tests/test_files/dicomdirtests/77654033/CT2/17106 b/pydicom/data/test_files/dicomdirtests/77654033/CT2/17106
similarity index 100%
rename from pydicom/tests/test_files/dicomdirtests/77654033/CT2/17106
rename to pydicom/data/test_files/dicomdirtests/77654033/CT2/17106
diff --git a/pydicom/tests/test_files/dicomdirtests/77654033/CT2/17136 b/pydicom/data/test_files/dicomdirtests/77654033/CT2/17136
similarity index 100%
rename from pydicom/tests/test_files/dicomdirtests/77654033/CT2/17136
rename to pydicom/data/test_files/dicomdirtests/77654033/CT2/17136
diff --git a/pydicom/tests/test_files/dicomdirtests/77654033/CT2/17166 b/pydicom/data/test_files/dicomdirtests/77654033/CT2/17166
similarity index 100%
rename from pydicom/tests/test_files/dicomdirtests/77654033/CT2/17166
rename to pydicom/data/test_files/dicomdirtests/77654033/CT2/17166
diff --git a/pydicom/tests/test_files/dicomdirtests/77654033/CT2/17196 b/pydicom/data/test_files/dicomdirtests/77654033/CT2/17196
similarity index 100%
rename from pydicom/tests/test_files/dicomdirtests/77654033/CT2/17196
rename to pydicom/data/test_files/dicomdirtests/77654033/CT2/17196
diff --git a/pydicom/data/test_files/dicomdirtests/77654033/__init__.py b/pydicom/data/test_files/dicomdirtests/77654033/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/pydicom/tests/test_files/dicomdirtests/98892001/CT2N/6293 b/pydicom/data/test_files/dicomdirtests/98892001/CT2N/6293
similarity index 100%
rename from pydicom/tests/test_files/dicomdirtests/98892001/CT2N/6293
rename to pydicom/data/test_files/dicomdirtests/98892001/CT2N/6293
diff --git a/pydicom/tests/test_files/dicomdirtests/98892001/CT2N/6924 b/pydicom/data/test_files/dicomdirtests/98892001/CT2N/6924
similarity index 100%
rename from pydicom/tests/test_files/dicomdirtests/98892001/CT2N/6924
rename to pydicom/data/test_files/dicomdirtests/98892001/CT2N/6924
diff --git a/pydicom/tests/test_files/dicomdirtests/98892001/CT5N/2062 b/pydicom/data/test_files/dicomdirtests/98892001/CT5N/2062
similarity index 100%
rename from pydicom/tests/test_files/dicomdirtests/98892001/CT5N/2062
rename to pydicom/data/test_files/dicomdirtests/98892001/CT5N/2062
diff --git a/pydicom/tests/test_files/dicomdirtests/98892001/CT5N/2392 b/pydicom/data/test_files/dicomdirtests/98892001/CT5N/2392
similarity index 100%
rename from pydicom/tests/test_files/dicomdirtests/98892001/CT5N/2392
rename to pydicom/data/test_files/dicomdirtests/98892001/CT5N/2392
diff --git a/pydicom/tests/test_files/dicomdirtests/98892001/CT5N/2693 b/pydicom/data/test_files/dicomdirtests/98892001/CT5N/2693
similarity index 100%
rename from pydicom/tests/test_files/dicomdirtests/98892001/CT5N/2693
rename to pydicom/data/test_files/dicomdirtests/98892001/CT5N/2693
diff --git a/pydicom/tests/test_files/dicomdirtests/98892001/CT5N/3023 b/pydicom/data/test_files/dicomdirtests/98892001/CT5N/3023
similarity index 100%
rename from pydicom/tests/test_files/dicomdirtests/98892001/CT5N/3023
rename to pydicom/data/test_files/dicomdirtests/98892001/CT5N/3023
diff --git a/pydicom/tests/test_files/dicomdirtests/98892001/CT5N/3353 b/pydicom/data/test_files/dicomdirtests/98892001/CT5N/3353
similarity index 100%
rename from pydicom/tests/test_files/dicomdirtests/98892001/CT5N/3353
rename to pydicom/data/test_files/dicomdirtests/98892001/CT5N/3353
diff --git a/pydicom/data/test_files/dicomdirtests/98892001/__init__.py b/pydicom/data/test_files/dicomdirtests/98892001/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/pydicom/tests/test_files/dicomdirtests/98892003/MR1/15820 b/pydicom/data/test_files/dicomdirtests/98892003/MR1/15820
similarity index 100%
rename from pydicom/tests/test_files/dicomdirtests/98892003/MR1/15820
rename to pydicom/data/test_files/dicomdirtests/98892003/MR1/15820
diff --git a/pydicom/tests/test_files/dicomdirtests/98892003/MR1/4919 b/pydicom/data/test_files/dicomdirtests/98892003/MR1/4919
similarity index 100%
rename from pydicom/tests/test_files/dicomdirtests/98892003/MR1/4919
rename to pydicom/data/test_files/dicomdirtests/98892003/MR1/4919
diff --git a/pydicom/tests/test_files/dicomdirtests/98892003/MR1/5641 b/pydicom/data/test_files/dicomdirtests/98892003/MR1/5641
similarity index 100%
rename from pydicom/tests/test_files/dicomdirtests/98892003/MR1/5641
rename to pydicom/data/test_files/dicomdirtests/98892003/MR1/5641
diff --git a/pydicom/tests/test_files/dicomdirtests/98892003/MR2/15970 b/pydicom/data/test_files/dicomdirtests/98892003/MR2/15970
similarity index 100%
rename from pydicom/tests/test_files/dicomdirtests/98892003/MR2/15970
rename to pydicom/data/test_files/dicomdirtests/98892003/MR2/15970
diff --git a/pydicom/tests/test_files/dicomdirtests/98892003/MR2/4950 b/pydicom/data/test_files/dicomdirtests/98892003/MR2/4950
similarity index 100%
rename from pydicom/tests/test_files/dicomdirtests/98892003/MR2/4950
rename to pydicom/data/test_files/dicomdirtests/98892003/MR2/4950
diff --git a/pydicom/tests/test_files/dicomdirtests/98892003/MR2/4981 b/pydicom/data/test_files/dicomdirtests/98892003/MR2/4981
similarity index 100%
rename from pydicom/tests/test_files/dicomdirtests/98892003/MR2/4981
rename to pydicom/data/test_files/dicomdirtests/98892003/MR2/4981
diff --git a/pydicom/tests/test_files/dicomdirtests/98892003/MR2/5011 b/pydicom/data/test_files/dicomdirtests/98892003/MR2/5011
similarity index 100%
rename from pydicom/tests/test_files/dicomdirtests/98892003/MR2/5011
rename to pydicom/data/test_files/dicomdirtests/98892003/MR2/5011
diff --git a/pydicom/tests/test_files/dicomdirtests/98892003/MR2/6273 b/pydicom/data/test_files/dicomdirtests/98892003/MR2/6273
similarity index 100%
rename from pydicom/tests/test_files/dicomdirtests/98892003/MR2/6273
rename to pydicom/data/test_files/dicomdirtests/98892003/MR2/6273
diff --git a/pydicom/tests/test_files/dicomdirtests/98892003/MR2/6605 b/pydicom/data/test_files/dicomdirtests/98892003/MR2/6605
similarity index 100%
rename from pydicom/tests/test_files/dicomdirtests/98892003/MR2/6605
rename to pydicom/data/test_files/dicomdirtests/98892003/MR2/6605
diff --git a/pydicom/tests/test_files/dicomdirtests/98892003/MR2/6935 b/pydicom/data/test_files/dicomdirtests/98892003/MR2/6935
similarity index 100%
rename from pydicom/tests/test_files/dicomdirtests/98892003/MR2/6935
rename to pydicom/data/test_files/dicomdirtests/98892003/MR2/6935
diff --git a/pydicom/tests/test_files/dicomdirtests/98892003/MR700/4467 b/pydicom/data/test_files/dicomdirtests/98892003/MR700/4467
similarity index 100%
rename from pydicom/tests/test_files/dicomdirtests/98892003/MR700/4467
rename to pydicom/data/test_files/dicomdirtests/98892003/MR700/4467
diff --git a/pydicom/tests/test_files/dicomdirtests/98892003/MR700/4528 b/pydicom/data/test_files/dicomdirtests/98892003/MR700/4528
similarity index 100%
rename from pydicom/tests/test_files/dicomdirtests/98892003/MR700/4528
rename to pydicom/data/test_files/dicomdirtests/98892003/MR700/4528
diff --git a/pydicom/tests/test_files/dicomdirtests/98892003/MR700/4558 b/pydicom/data/test_files/dicomdirtests/98892003/MR700/4558
similarity index 100%
rename from pydicom/tests/test_files/dicomdirtests/98892003/MR700/4558
rename to pydicom/data/test_files/dicomdirtests/98892003/MR700/4558
diff --git a/pydicom/tests/test_files/dicomdirtests/98892003/MR700/4588 b/pydicom/data/test_files/dicomdirtests/98892003/MR700/4588
similarity index 100%
rename from pydicom/tests/test_files/dicomdirtests/98892003/MR700/4588
rename to pydicom/data/test_files/dicomdirtests/98892003/MR700/4588
diff --git a/pydicom/tests/test_files/dicomdirtests/98892003/MR700/4618 b/pydicom/data/test_files/dicomdirtests/98892003/MR700/4618
similarity index 100%
rename from pydicom/tests/test_files/dicomdirtests/98892003/MR700/4618
rename to pydicom/data/test_files/dicomdirtests/98892003/MR700/4618
diff --git a/pydicom/tests/test_files/dicomdirtests/98892003/MR700/4648 b/pydicom/data/test_files/dicomdirtests/98892003/MR700/4648
similarity index 100%
rename from pydicom/tests/test_files/dicomdirtests/98892003/MR700/4648
rename to pydicom/data/test_files/dicomdirtests/98892003/MR700/4648
diff --git a/pydicom/tests/test_files/dicomdirtests/98892003/MR700/4678 b/pydicom/data/test_files/dicomdirtests/98892003/MR700/4678
similarity index 100%
rename from pydicom/tests/test_files/dicomdirtests/98892003/MR700/4678
rename to pydicom/data/test_files/dicomdirtests/98892003/MR700/4678
diff --git a/pydicom/data/test_files/dicomdirtests/98892003/__init__.py b/pydicom/data/test_files/dicomdirtests/98892003/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/pydicom/tests/test_files/dicomdirtests/DICOMDIR b/pydicom/data/test_files/dicomdirtests/DICOMDIR
similarity index 100%
rename from pydicom/tests/test_files/dicomdirtests/DICOMDIR
rename to pydicom/data/test_files/dicomdirtests/DICOMDIR
diff --git a/pydicom/data/test_files/dicomdirtests/__init__.py b/pydicom/data/test_files/dicomdirtests/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/pydicom/tests/test_files/emri_small.dcm b/pydicom/data/test_files/emri_small.dcm
similarity index 100%
rename from pydicom/tests/test_files/emri_small.dcm
rename to pydicom/data/test_files/emri_small.dcm
diff --git a/pydicom/tests/test_files/emri_small_RLE.dcm b/pydicom/data/test_files/emri_small_RLE.dcm
similarity index 100%
rename from pydicom/tests/test_files/emri_small_RLE.dcm
rename to pydicom/data/test_files/emri_small_RLE.dcm
diff --git a/pydicom/tests/test_files/emri_small_big_endian.dcm b/pydicom/data/test_files/emri_small_big_endian.dcm
similarity index 100%
rename from pydicom/tests/test_files/emri_small_big_endian.dcm
rename to pydicom/data/test_files/emri_small_big_endian.dcm
diff --git a/pydicom/tests/test_files/emri_small_jpeg_2k_lossless.dcm b/pydicom/data/test_files/emri_small_jpeg_2k_lossless.dcm
similarity index 100%
rename from pydicom/tests/test_files/emri_small_jpeg_2k_lossless.dcm
rename to pydicom/data/test_files/emri_small_jpeg_2k_lossless.dcm
diff --git a/pydicom/tests/test_files/emri_small_jpeg_ls_lossless.dcm b/pydicom/data/test_files/emri_small_jpeg_ls_lossless.dcm
similarity index 100%
rename from pydicom/tests/test_files/emri_small_jpeg_ls_lossless.dcm
rename to pydicom/data/test_files/emri_small_jpeg_ls_lossless.dcm
diff --git a/pydicom/tests/test_files/image_dfl.dcm b/pydicom/data/test_files/image_dfl.dcm
similarity index 100%
rename from pydicom/tests/test_files/image_dfl.dcm
rename to pydicom/data/test_files/image_dfl.dcm
diff --git a/pydicom/tests/test_files/meta_missing_tsyntax.dcm b/pydicom/data/test_files/meta_missing_tsyntax.dcm
similarity index 100%
rename from pydicom/tests/test_files/meta_missing_tsyntax.dcm
rename to pydicom/data/test_files/meta_missing_tsyntax.dcm
diff --git a/pydicom/tests/test_files/nested_priv_SQ.dcm b/pydicom/data/test_files/nested_priv_SQ.dcm
similarity index 100%
rename from pydicom/tests/test_files/nested_priv_SQ.dcm
rename to pydicom/data/test_files/nested_priv_SQ.dcm
diff --git a/pydicom/tests/test_files/no_meta_group_length.dcm b/pydicom/data/test_files/no_meta_group_length.dcm
similarity index 100%
rename from pydicom/tests/test_files/no_meta_group_length.dcm
rename to pydicom/data/test_files/no_meta_group_length.dcm
diff --git a/pydicom/tests/test_files/priv_SQ.dcm b/pydicom/data/test_files/priv_SQ.dcm
similarity index 100%
rename from pydicom/tests/test_files/priv_SQ.dcm
rename to pydicom/data/test_files/priv_SQ.dcm
diff --git a/pydicom/tests/test_files/reportsi.dcm b/pydicom/data/test_files/reportsi.dcm
similarity index 100%
rename from pydicom/tests/test_files/reportsi.dcm
rename to pydicom/data/test_files/reportsi.dcm
diff --git a/pydicom/tests/test_files/reportsi_with_empty_number_tags.dcm b/pydicom/data/test_files/reportsi_with_empty_number_tags.dcm
similarity index 100%
rename from pydicom/tests/test_files/reportsi_with_empty_number_tags.dcm
rename to pydicom/data/test_files/reportsi_with_empty_number_tags.dcm
diff --git a/pydicom/tests/test_files/rtdose.dcm b/pydicom/data/test_files/rtdose.dcm
similarity index 100%
rename from pydicom/tests/test_files/rtdose.dcm
rename to pydicom/data/test_files/rtdose.dcm
diff --git a/pydicom/tests/test_files/rtplan.dcm b/pydicom/data/test_files/rtplan.dcm
similarity index 100%
rename from pydicom/tests/test_files/rtplan.dcm
rename to pydicom/data/test_files/rtplan.dcm
diff --git a/pydicom/tests/test_files/rtplan.dump b/pydicom/data/test_files/rtplan.dump
similarity index 100%
rename from pydicom/tests/test_files/rtplan.dump
rename to pydicom/data/test_files/rtplan.dump
diff --git a/pydicom/tests/test_files/rtplan_truncated.dcm b/pydicom/data/test_files/rtplan_truncated.dcm
similarity index 100%
rename from pydicom/tests/test_files/rtplan_truncated.dcm
rename to pydicom/data/test_files/rtplan_truncated.dcm
diff --git a/pydicom/tests/test_files/rtstruct.dcm b/pydicom/data/test_files/rtstruct.dcm
similarity index 100%
rename from pydicom/tests/test_files/rtstruct.dcm
rename to pydicom/data/test_files/rtstruct.dcm
diff --git a/pydicom/tests/test_files/rtstruct.dump b/pydicom/data/test_files/rtstruct.dump
similarity index 100%
rename from pydicom/tests/test_files/rtstruct.dump
rename to pydicom/data/test_files/rtstruct.dump
diff --git a/pydicom/tests/test_files/test-SR.dcm b/pydicom/data/test_files/test-SR.dcm
similarity index 100%
rename from pydicom/tests/test_files/test-SR.dcm
rename to pydicom/data/test_files/test-SR.dcm
diff --git a/pydicom/tests/test_files/test.py b/pydicom/data/test_files/test.py
similarity index 100%
rename from pydicom/tests/test_files/test.py
rename to pydicom/data/test_files/test.py
diff --git a/pydicom/tests/test_files/zipMR.gz b/pydicom/data/test_files/zipMR.gz
similarity index 100%
rename from pydicom/tests/test_files/zipMR.gz
rename to pydicom/data/test_files/zipMR.gz
diff --git a/pydicom/data/utils.py b/pydicom/data/utils.py
new file mode 100644
index 000000000..7ae8f09cd
--- /dev/null
+++ b/pydicom/data/utils.py
@@ -0,0 +1,48 @@
+"""pydicom data manager utils"""
+#
+# Copyright (c) 2008-2012 Darcy Mason
+# Copyright (c) 2017 pydicom AUTHORS
+# This file is part of pydicom, released under a modified MIT license.
+#    See the file LICENSE included with this distribution, also
+#    available at https://github.com/pydicom/pydicom
+#
+
+import os
+import fnmatch
+
+
+def get_files(bases, pattern=None):
+    """Return all files from a set of sources.
+
+    Parameters
+    ----------
+    bases : list or file-like
+            This can be a list of files and/or folders conforming
+            to some standard pattern.
+    pattern : string for fnmatch
+            A string pattern to filter the files
+
+    Returns
+    ----------
+    files : list of files recursively found
+            from the bases
+    """
+
+    if pattern is None:
+        pattern = "*"
+
+    if not isinstance(bases, (list, tuple)):
+        bases = [bases]
+
+    files = []
+    for contender in bases:
+        if os.path.isdir(contender):
+
+            for root, dirnames, filenames in os.walk(contender):
+                for filename in fnmatch.filter(filenames, pattern):
+                    files.append(os.path.join(root, filename))
+
+        else:
+            files.append(contender)
+
+    return files
diff --git a/setup.py b/setup.py
index ae1d69e28..a570e76d3 100755
--- a/setup.py
+++ b/setup.py
@@ -1,7 +1,10 @@
 #!/usr/bin/env python
+
+import os
+from glob import glob
 from setuptools import setup, find_packages
-from pydicom import __version__
 
+from pydicom import __version__
 
 description = "Pure python package for DICOM medical file reading and writing"
 
@@ -52,9 +55,22 @@ URL = "https://github.com/pydicom/pydicom"
 DOWNLOAD_URL = "https://github.com/pydicom/pydicom/archive/master.zip"
 LICENSE = "MIT"
 VERSION = __version__
-PACKAGE_DATA = {'pydicom': ['tests/test_files/*', 'tests/charset_files/*']}
 REQUIRES = []
 
+
+def data_files_inventory():
+    data_files = []
+    data_roots = ['pydicom/data']
+    for data_root in data_roots:
+        for root, subfolder, files in os.walk(data_root):
+            files = [x.replace('pydicom/', '') for x in glob(root + '/*')
+                     if not os.path.isdir(x)]
+            data_files = data_files + files
+    return data_files
+
+
+PACKAGE_DATA = {'pydicom': data_files_inventory()}
+
 opts = dict(name=NAME,
             version=__version__,
             maintainer=MAINTAINER,


Test patch:
diff --git a/pydicom/tests/test_JPEG_LS_transfer_syntax.py b/pydicom/tests/test_JPEG_LS_transfer_syntax.py
index a6b164a2c..a069ae9d3 100644
--- a/pydicom/tests/test_JPEG_LS_transfer_syntax.py
+++ b/pydicom/tests/test_JPEG_LS_transfer_syntax.py
@@ -4,6 +4,7 @@ import re
 import pytest
 import pydicom
 from pydicom.filereader import read_file
+from pydicom.data import DATA_ROOT
 pillow_missing_message = ("pillow is not available "
                           "in this test environment")
 pillow_present_message = "pillow is being tested"
@@ -39,8 +40,7 @@ try:
 except ImportError:
     gdcm_handler = None
 
-test_dir = os.path.dirname(__file__)
-test_files = os.path.join(test_dir, 'test_files')
+test_files = os.path.join(DATA_ROOT, 'test_files')
 
 mr_name = os.path.join(test_files, "MR_small.dcm")
 jpeg_ls_lossless_name = os.path.join(
diff --git a/pydicom/tests/test_RLE_transfer_syntax.py b/pydicom/tests/test_RLE_transfer_syntax.py
index 020cb0af2..0004cc6bf 100644
--- a/pydicom/tests/test_RLE_transfer_syntax.py
+++ b/pydicom/tests/test_RLE_transfer_syntax.py
@@ -4,6 +4,7 @@ import re
 import pytest
 import pydicom
 from pydicom.filereader import read_file
+from pydicom.data import DATA_ROOT
 pillow_missing_message = ("pillow is not available "
                           "in this test environment")
 pillow_present_message = "pillow is being tested"
@@ -39,8 +40,7 @@ try:
 except ImportError:
     gdcm_handler = None
 
-test_dir = os.path.dirname(__file__)
-test_files = os.path.join(test_dir, 'test_files')
+test_files = os.path.join(DATA_ROOT, 'test_files')
 
 mr_name = os.path.join(test_files, "MR_small.dcm")
 compressed_mr_name = os.path.join(
diff --git a/pydicom/tests/test_charset.py b/pydicom/tests/test_charset.py
index e54f516c8..2396920dc 100644
--- a/pydicom/tests/test_charset.py
+++ b/pydicom/tests/test_charset.py
@@ -7,20 +7,19 @@
 #    available at https://github.com/pydicom/pydicom
 
 import unittest
+from pydicom.data import DATA_ROOT
 from pydicom import dicomio
 import os.path
 import pydicom.charset
 
-test_dir = os.path.dirname(__file__)
-testcharset_dir = os.path.join(test_dir, 'charset_files')
+testcharset_dir = os.path.join(DATA_ROOT, 'charset_files')
+test_files = os.path.join(DATA_ROOT, 'test_files')
 
 latin1_file = os.path.join(testcharset_dir, "chrFren.dcm")
 jp_file = os.path.join(testcharset_dir, "chrH31.dcm")
 multiPN_file = os.path.join(testcharset_dir, "chrFrenMulti.dcm")
 sq_encoding_file = os.path.join(testcharset_dir, "chrSQEncoding.dcm")
 explicit_ir6_file = os.path.join(testcharset_dir, "chrJapMultiExplicitIR6.dcm")
-
-test_files = os.path.join(test_dir, 'test_files')
 normal_file = os.path.join(test_files, "CT_small.dcm")
 
 
diff --git a/pydicom/tests/test_dataset.py b/pydicom/tests/test_dataset.py
index 9d8a200c7..d9d0ed4c9 100644
--- a/pydicom/tests/test_dataset.py
+++ b/pydicom/tests/test_dataset.py
@@ -9,6 +9,7 @@ import os
 import unittest
 
 from pydicom.dataset import Dataset
+from pydicom.data import DATA_ROOT
 from pydicom.dataelem import DataElement, RawDataElement
 from pydicom.dicomio import read_file
 from pydicom.filebase import DicomBytesIO
@@ -821,8 +822,9 @@ class DatasetElementsTests(unittest.TestCase):
 
 class FileDatasetTests(unittest.TestCase):
     def setUp(self):
-        test_dir = os.path.dirname(__file__)
-        self.test_file = os.path.join(test_dir, 'test_files', 'CT_small.dcm')
+        self.test_file = os.path.join(DATA_ROOT,
+                                      'test_files',
+                                      'CT_small.dcm')
 
     def testEqualityFileMeta(self):
         """Dataset: equality returns correct value if with metadata"""
diff --git a/pydicom/tests/test_filereader.py b/pydicom/tests/test_filereader.py
index 9a399db03..24b2f4630 100644
--- a/pydicom/tests/test_filereader.py
+++ b/pydicom/tests/test_filereader.py
@@ -16,6 +16,7 @@ import tempfile
 import unittest
 from pydicom.util.testing.warncheck import assertWarns
 from pydicom.dataset import Dataset, FileDataset
+from pydicom.data import DATA_ROOT
 from pydicom.dataelem import DataElement
 from pydicom.filereader import read_file
 from pydicom.errors import InvalidDicomError
@@ -66,8 +67,7 @@ have_numpy = numpy is not None
 have_jpeg_ls = jpeg_ls is not None
 have_pillow = PILImg is not None
 
-test_dir = os.path.dirname(__file__)
-test_files = os.path.join(test_dir, 'test_files')
+test_files = os.path.join(DATA_ROOT, 'test_files')
 
 empty_number_tags_name = os.path.join(test_files,
                                       "reportsi_with_empty_number_tags.dcm")
diff --git a/pydicom/tests/test_filewriter.py b/pydicom/tests/test_filewriter.py
index fb774dcc7..e86a393a9 100644
--- a/pydicom/tests/test_filewriter.py
+++ b/pydicom/tests/test_filewriter.py
@@ -13,12 +13,12 @@ import os.path
 from struct import unpack
 import sys
 from tempfile import TemporaryFile
-import unittest
 
 import pytest
 
 from pydicom._storage_sopclass_uids import CTImageStorage
 from pydicom import config, __version__
+from pydicom.data import DATA_ROOT
 from pydicom.dataset import Dataset, FileDataset
 from pydicom.dataelem import DataElement
 from pydicom.filebase import DicomBytesIO
@@ -31,16 +31,23 @@ from pydicom.uid import (ImplicitVRLittleEndian, ExplicitVRBigEndian,
                          PYDICOM_IMPLEMENTATION_UID)
 from pydicom.util.hexutil import hex2bytes, bytes2hex
 from pydicom.valuerep import DA, DT, TM
+import unittest
 
 have_dateutil = True
 try:
     from dateutil.tz import tzoffset
 except ImportError:
     have_dateutil = False
+try:
+    unittest.TestCase.assertSequenceEqual
+except AttributeError:
+    try:
+        import unittest2 as unittest
+    except ImportError:
+        print("unittest2 is required for testing in python2.6")
 
-test_dir = os.path.dirname(__file__)
-test_files = os.path.join(test_dir, 'test_files')
-testcharset_dir = os.path.join(test_dir, 'charset_files')
+test_files = os.path.join(DATA_ROOT, 'test_files')
+testcharset_dir = os.path.join(DATA_ROOT, 'charset_files')
 
 rtplan_name = os.path.join(test_files, "rtplan.dcm")
 rtdose_name = os.path.join(test_files, "rtdose.dcm")
@@ -65,16 +72,17 @@ def files_identical(a, b):
 
 
 def bytes_identical(a_bytes, b_bytes):
-    """Return a tuple (bytes a == bytes b, index of first difference)"""
+    """Return a tuple
+       (bytes a == bytes b, index of first difference)"""
     if len(a_bytes) != len(b_bytes):
         return False, min([len(a_bytes), len(b_bytes)])
     elif a_bytes == b_bytes:
-        return True, 0     # True, dummy argument
+        return True, 0  # True, dummy argument
     else:
         pos = 0
         while a_bytes[pos] == b_bytes[pos]:
             pos += 1
-        return False, pos   # False if not identical, position of 1st diff
+        return False, pos  # False if not identical, position of 1st diff
 
 
 class WriteFileTests(unittest.TestCase):
@@ -82,7 +90,8 @@ class WriteFileTests(unittest.TestCase):
         self.file_out = TemporaryFile('w+b')
 
     def compare(self, in_filename, decode=False):
-        """Read Dataset from `in_filename`, write to file, then compare."""
+        """Read Dataset from in_filename, write to file, compare"""
+
         with open(in_filename, 'rb') as f:
             bytes_in = BytesIO(f.read())
             bytes_in.seek(0)
@@ -104,35 +113,43 @@ class WriteFileTests(unittest.TestCase):
                         "difference at 0x%x" % pos)
 
     def testRTPlan(self):
-        """Input file, write back and verify them identical (RT Plan file)"""
+        """Input file, write back and verify
+           them identical (RT Plan file)"""
         self.compare(rtplan_name)
 
     def testRTDose(self):
-        """Input file, write back and verify them identical (RT Dose file)"""
+        """Input file, write back and
+           verify them identical (RT Dose file)"""
         self.compare(rtdose_name)
 
     def testCT(self):
-        """Input file, write back and verify them identical (CT file)....."""
+        """Input file, write back and
+           verify them identical (CT file)....."""
         self.compare(ct_name)
 
     def testMR(self):
-        """Input file, write back and verify them identical (MR file)....."""
+        """Input file, write back and verify
+           them identical (MR file)....."""
         self.compare(mr_name)
 
     def testUnicode(self):
-        """Ensure decoded string DataElements are written to file properly"""
+        """Ensure decoded string DataElements
+           are written to file properly"""
         self.compare(unicode_name, decode=True)
 
     def testMultiPN(self):
-        """Ensure multiple Person Names are written to the file correctly."""
+        """Ensure multiple Person Names are written
+           to the file correctly."""
         self.compare(multiPN_name, decode=True)
 
     def testJPEG2000(self):
-        """Input file, write back and verify them identical (JPEG2K file)."""
+        """Input file, write back and verify
+           them identical (JPEG2K file)."""
         self.compare(jpeg_name)
 
     def testListItemWriteBack(self):
-        """Change item in a list and confirm it is written to file      .."""
+        """Change item in a list and confirm
+          it is written to file"""
         DS_expected = 0
         CS_expected = "new"
         SS_expected = 999
@@ -208,6 +225,7 @@ class ScratchWriteDateTimeTests(WriteFileTests):
         self.file_out.seek(0)
         # Now read it back in and check the values are as expected
         ds = read_file(self.file_out)
+
         self.assertSequenceEqual(multi_DA_expected, ds.CalibrationDate)
         self.assertEqual(DA_expected, ds.DateOfLastCalibration)
         self.assertSequenceEqual(multi_DT_expected, ds.ReferencedDateTime)
@@ -297,10 +315,12 @@ class WriteDataElementTests(unittest.TestCase):
         # VR (OD): \x4f\x44
         # Reserved: \x00\x00
         # Length (16): \x10\x00\x00\x00
+
         #             | Tag          | VR    |
         ref_bytes = b'\x70\x00\x0d\x15\x4f\x44' \
                     b'\x00\x00\x10\x00\x00\x00' + bytestring
         #             |Rsrvd |   Length      |    Value ->
+
         self.assertEqual(encoded_elem, ref_bytes)
 
         # Empty data
@@ -343,10 +363,12 @@ class WriteDataElementTests(unittest.TestCase):
         # VR (OL): \x4f\x4c
         # Reserved: \x00\x00
         # Length (12): 0c 00 00 00
+
         #             | Tag          | VR    |
         ref_bytes = b'\x66\x00\x29\x01\x4f\x4c' \
                     b'\x00\x00\x0c\x00\x00\x00' + bytestring
         #             |Rsrvd |   Length      |    Value ->
+
         self.assertEqual(encoded_elem, ref_bytes)
 
         # Empty data
@@ -465,7 +487,8 @@ class WriteDataElementTests(unittest.TestCase):
         # Empty value
         elem.value = ''
         encoded_elem = self.encode_element(elem)
-        self.assertEqual(encoded_elem, b'\x08\x00\x20\x01\x00\x00\x00\x00')
+        self.assertEqual(encoded_elem,
+                         b'\x08\x00\x20\x01\x00\x00\x00\x00')
 
     def test_write_UR_explicit_little(self):
         """Test writing elements with VR of UR works correctly.
@@ -692,6 +715,7 @@ class TestCorrectAmbiguousVR(unittest.TestCase):
         ref_ds.BeamSequence[0].PixelRepresentation = 0
         ref_ds.BeamSequence[0].SmallestValidPixelValue = b'\x00\x01'
         ref_ds.BeamSequence[0].BeamSequence = [Dataset()]
+
         ref_ds.BeamSequence[0].BeamSequence[0].PixelRepresentation = 0
         ref_ds.BeamSequence[0].BeamSequence[0].SmallestValidPixelValue = \
             b'\x00\x01'
@@ -799,16 +823,17 @@ class ScratchWriteTests(unittest.TestCase):
         # print "std    :", bytes2hex(std)
         # print "written:", bytes2hex(bytes_written)
         same, pos = bytes_identical(std, bytes_written)
+
         self.assertTrue(same,
                         "Writing from scratch unexpected result "
                         "- 1st diff at 0x%x" % pos)
+
         if os.path.exists(out_filename):
             os.remove(out_filename)  # get rid of the file
 
     def testImpl_LE_deflen_write(self):
-        """Scratch Write for implicit VR little endian, defined length SQ's"""
+        """Scratch Write for implicit VR little endian, defined length SQs"""
         from pydicom.util.testing._write_stds import impl_LE_deflen_std_hex
-
         file_ds = FileDataset("test", self.ds)
         self.compare_write(impl_LE_deflen_std_hex, file_ds)
 
@@ -820,7 +845,8 @@ class TestWriteToStandard(unittest.TestCase):
         self.fp = BytesIO()
 
     def test_preamble_default(self):
-        """Test that the default preamble is written correctly when present."""
+        """Test that the default preamble is
+           written correctly when present."""
         ds = read_file(ct_name)
         ds.preamble = b'\x00' * 128
         ds.save_as(self.fp, write_like_original=False)
@@ -828,11 +854,13 @@ class TestWriteToStandard(unittest.TestCase):
         self.assertEqual(self.fp.read(128), b'\x00' * 128)
 
     def test_preamble_custom(self):
-        """Test that a custom preamble is written correctly when present."""
+        """Test that a custom preamble is
+           written correctly when present."""
         ds = read_file(ct_name)
         ds.preamble = b'\x01\x02\x03\x04' + b'\x00' * 124
         ds.save_as(self.fp, write_like_original=False)
         self.fp.seek(0)
+
         assert self.fp.read(128) == b'\x01\x02\x03\x04' + b'\x00' * 124
 
     def test_no_preamble(self):
@@ -862,7 +890,8 @@ class TestWriteToStandard(unittest.TestCase):
             ds.save_as(self.fp, write_like_original=False)
 
     def test_prefix(self):
-        """Test that the 'DICM' prefix is written with preamble."""
+        """Test that the 'DICM' prefix
+           is written with preamble."""
         # Has preamble
         ds = read_file(ct_name)
         ds.preamble = b'\x00' * 128
@@ -871,7 +900,8 @@ class TestWriteToStandard(unittest.TestCase):
         self.assertEqual(self.fp.read(4), b'DICM')
 
     def test_prefix_none(self):
-        """Test the 'DICM' prefix is written when preamble is None"""
+        """Test the 'DICM' prefix is written
+           when preamble is None"""
         ds = read_file(ct_name)
         ds.preamble = None
         ds.save_as(self.fp, write_like_original=False)
@@ -899,12 +929,14 @@ class TestWriteToStandard(unittest.TestCase):
         ds.is_implicit_VR = True
         ds.is_little_endian = True
         ds.save_as(self.fp, write_like_original=False)
+
         assert ds.file_meta.TransferSyntaxUID == ImplicitVRLittleEndian
 
         # Updated
         ds.is_implicit_VR = False
         ds.is_little_endian = False
         ds.save_as(self.fp, write_like_original=False)
+
         assert ds.file_meta.TransferSyntaxUID == ExplicitVRBigEndian
 
     def test_transfer_syntax_not_added(self):
@@ -913,15 +945,19 @@ class TestWriteToStandard(unittest.TestCase):
         del ds.file_meta.TransferSyntaxUID
         ds.is_implicit_VR = False
         ds.is_little_endian = True
+
         with pytest.raises(ValueError):
             ds.save_as(self.fp, write_like_original=False)
+
         self.assertFalse('TransferSyntaxUID' in ds.file_meta)
 
     def test_transfer_syntax_raises(self):
-        """Test TransferSyntaxUID is raises NotImplementedError if ImplVRBE."""
+        """Test TransferSyntaxUID is raises
+           NotImplementedError if ImplVRBE."""
         ds = read_file(rtplan_name)
         ds.is_implicit_VR = True
         ds.is_little_endian = False
+
         with pytest.raises(NotImplementedError):
             ds.save_as(self.fp, write_like_original=False)
 
@@ -953,6 +989,7 @@ class TestWriteToStandard(unittest.TestCase):
 
     def test_commandset_no_written(self):
         """Test that Command Set elements aren't written"""
+
         ds = read_file(ct_name)
         preamble = ds.preamble[:]
         ds.MessageID = 3
@@ -1014,7 +1051,8 @@ class TestWriteFileMetaInfoToStandard(unittest.TestCase):
         self.assertEqual(self.fp.read(4), b'\x3E\x00\x00\x00')
 
     def test_group_length_updated(self):
-        """Test that FileMetaInformationGroupLength gets updated if present."""
+        """Test that FileMetaInformationGroupLength
+           gets updated if present."""
         meta = Dataset()
         meta.FileMetaInformationGroupLength = 100  # Not actual length
         meta.MediaStorageSOPClassUID = '1.1'
@@ -1040,7 +1078,8 @@ class TestWriteFileMetaInfoToStandard(unittest.TestCase):
         meta.MediaStorageSOPInstanceUID = '1.2'
         meta.TransferSyntaxUID = '1.3'
         meta.ImplementationClassUID = '1.4'
-        write_file_meta_info(self.fp, meta, enforce_standard=True)
+        write_file_meta_info(self.fp, meta,
+                             enforce_standard=True)
 
         self.fp.seek(12 + 12)
         self.assertEqual(self.fp.read(2), b'\x00\x01')
@@ -1059,19 +1098,22 @@ class TestWriteFileMetaInfoToStandard(unittest.TestCase):
         meta.MediaStorageSOPInstanceUID = '1.2'
         meta.TransferSyntaxUID = '1.3'
         meta.ImplementationClassUID = '1.4'
-        write_file_meta_info(self.fp, meta, enforce_standard=True)
+        write_file_meta_info(self.fp, meta,
+                             enforce_standard=True)
         self.assertEqual(self.fp.tell(), 74)
 
         # 8 + 6 bytes ImplementationClassUID
         # 76 bytes total, group length 64
         self.fp.seek(0)
         meta.ImplementationClassUID = '1.4.1'
-        write_file_meta_info(self.fp, meta, enforce_standard=True)
+        write_file_meta_info(self.fp, meta,
+                             enforce_standard=True)
         # Check File Meta length
         self.assertEqual(self.fp.tell(), 76)
         # Check Group Length
         self.fp.seek(8)
-        self.assertEqual(self.fp.read(4), b'\x40\x00\x00\x00')
+        self.assertEqual(self.fp.read(4),
+                         b'\x40\x00\x00\x00')
 
 
 class TestWriteNonStandard(unittest.TestCase):
@@ -1089,7 +1131,8 @@ class TestWriteNonStandard(unittest.TestCase):
                         "difference at 0x%x" % pos)
 
     def test_preamble_default(self):
-        """Test that the default preamble is written correctly when present."""
+        """Test that the default preamble is
+           written correctly when present."""
         ds = read_file(ct_name)
         ds.preamble = b'\x00' * 128
         ds.save_as(self.fp, write_like_original=True)
@@ -1097,7 +1140,8 @@ class TestWriteNonStandard(unittest.TestCase):
         self.assertEqual(self.fp.read(128), b'\x00' * 128)
 
     def test_preamble_custom(self):
-        """Test that a custom preamble is written correctly when present."""
+        """Test that a custom preamble is
+           written correctly when present."""
         ds = read_file(ct_name)
         ds.preamble = b'\x01\x02\x03\x04' + b'\x00' * 124
         self.fp.seek(0)
@@ -1107,7 +1151,8 @@ class TestWriteNonStandard(unittest.TestCase):
                          b'\x01\x02\x03\x04' + b'\x00' * 124)
 
     def test_no_preamble(self):
-        """Test no preamble or prefix is written if preamble absent."""
+        """Test no preamble or prefix is written
+           if preamble absent."""
         ds = read_file(ct_name)
         preamble = ds.preamble[:]
         del ds.preamble
@@ -1278,7 +1323,8 @@ class TestWriteNonStandard(unittest.TestCase):
         self.assertTrue('PatientID' in ds_out)
 
     def test_commandset_filemeta_dataset(self):
-        """Test written OK with command set/file meta/dataset"""
+        """Test written OK with command
+           set/file meta/dataset"""
         ds = read_file(ct_name)
         preamble = ds.preamble[:]
         del ds.preamble
@@ -1288,9 +1334,11 @@ class TestWriteNonStandard(unittest.TestCase):
         ds.Status = 0x0000
         ds.save_as(self.fp, write_like_original=True)
         self.fp.seek(0)
-        self.assertNotEqual(self.fp.read(128), preamble)
+        self.assertNotEqual(self.fp.read(128),
+                            preamble)
         self.fp.seek(0)
-        self.assertNotEqual(self.fp.read(128), b'\x00' * 128)
+        self.assertNotEqual(self.fp.read(128),
+                            b'\x00' * 128)
         self.fp.seek(0)
         self.assertNotEqual(self.fp.read(4), b'DICM')
         # Ensure Command Set Elements written as little endian implicit VR
diff --git a/pydicom/tests/test_gdcm_pixel_data.py b/pydicom/tests/test_gdcm_pixel_data.py
index a55afaa33..1d0844135 100644
--- a/pydicom/tests/test_gdcm_pixel_data.py
+++ b/pydicom/tests/test_gdcm_pixel_data.py
@@ -5,6 +5,7 @@ import pytest
 import pydicom
 import logging
 from pydicom.filereader import read_file
+from pydicom.data import DATA_ROOT
 from pydicom.tag import Tag
 gdcm_missing_message = "GDCM is not available in this test environment"
 gdcm_present_message = "GDCM is being tested"
@@ -18,8 +19,7 @@ except ImportError as e:
 
 test_gdcm_decoder = have_gdcm_handler
 
-test_dir = os.path.dirname(__file__)
-test_files = os.path.join(test_dir, 'test_files')
+test_files = os.path.join(DATA_ROOT, 'test_files')
 
 empty_number_tags_name = os.path.join(
     test_files, "reportsi_with_empty_number_tags.dcm")
diff --git a/pydicom/tests/test_getdata.py b/pydicom/tests/test_getdata.py
new file mode 100644
index 000000000..59e0a78b1
--- /dev/null
+++ b/pydicom/tests/test_getdata.py
@@ -0,0 +1,41 @@
+"""Test the data manager"""
+
+import os
+import unittest
+from os.path import basename
+from pydicom.data import (get_charset_files,
+                          get_testdata_files)
+
+from pydicom.data.base import DATA_ROOT
+
+
+class TestGetData(unittest.TestCase):
+
+    def test_get_dataset(self):
+        """Test the different functions
+        to get lists of data files"""
+
+        # Test base locations
+        charbase = os.path.join(DATA_ROOT, 'charset_files')
+        self.assertTrue(os.path.exists(charbase))
+
+        testbase = os.path.join(DATA_ROOT, 'test_files')
+        self.assertTrue(os.path.exists(testbase))
+
+        # Test file get
+        chardata = get_charset_files()
+        self.assertTrue(len(chardata) > 15)
+
+        # Test that top level file is included
+        bases = [basename(x) for x in chardata]
+        self.assertTrue('charlist.py' in bases)
+
+        # Test that subdirectory files included
+        testdata = get_testdata_files()
+        bases = [basename(x) for x in testdata]
+        self.assertTrue('2693' in bases)
+        self.assertTrue(len(testdata) > 70)
+
+        # The files should be from their respective bases
+        [self.assertTrue(testbase in x) for x in testdata]
+        [self.assertTrue(charbase in x) for x in chardata]
diff --git a/pydicom/tests/test_jpeg_ls_pixel_data.py b/pydicom/tests/test_jpeg_ls_pixel_data.py
index b3054a6b7..b5f2a07c3 100644
--- a/pydicom/tests/test_jpeg_ls_pixel_data.py
+++ b/pydicom/tests/test_jpeg_ls_pixel_data.py
@@ -4,6 +4,7 @@ import sys
 import pytest
 import pydicom
 from pydicom.filereader import read_file
+from pydicom.data import DATA_ROOT
 jpeg_ls_missing_message = ("jpeg_ls is not available "
                            "in this test environment")
 jpeg_ls_present_message = "jpeg_ls is being tested"
@@ -22,8 +23,7 @@ except ImportError:
 
 test_jpeg_ls_decoder = have_numpy_handler and have_jpeg_ls_handler
 
-test_dir = os.path.dirname(__file__)
-test_files = os.path.join(test_dir, 'test_files')
+test_files = os.path.join(DATA_ROOT, 'test_files')
 
 empty_number_tags_name = os.path.join(
     test_files, "reportsi_with_empty_number_tags.dcm")
diff --git a/pydicom/tests/test_misc.py b/pydicom/tests/test_misc.py
index 040938495..d42f7f4c5 100644
--- a/pydicom/tests/test_misc.py
+++ b/pydicom/tests/test_misc.py
@@ -3,10 +3,11 @@
 import unittest
 import os.path as osp
 
+from pydicom.data import DATA_ROOT
 from pydicom.misc import is_dicom, size_in_bytes
 
-test_file = osp.join(osp.dirname(osp.abspath(__file__)), 'test_files',
-                     'CT_small.dcm')
+test_files = osp.join(DATA_ROOT, 'test_files')
+test_file = osp.join(test_files, 'CT_small.dcm')
 
 
 class TestMisc(unittest.TestCase):
diff --git a/pydicom/tests/test_numpy_pixel_data.py b/pydicom/tests/test_numpy_pixel_data.py
index 1f6a244e0..6c078c041 100644
--- a/pydicom/tests/test_numpy_pixel_data.py
+++ b/pydicom/tests/test_numpy_pixel_data.py
@@ -4,6 +4,7 @@ import sys
 import pytest
 import pydicom
 from pydicom.filereader import read_file
+from pydicom.data import DATA_ROOT
 from pydicom.tag import Tag
 numpy_missing_message = ("numpy is not available "
                          "in this test environment")
@@ -15,8 +16,7 @@ try:
 except ImportError:
     have_numpy_handler = False
 
-test_dir = os.path.dirname(__file__)
-test_files = os.path.join(test_dir, 'test_files')
+test_files = os.path.join(DATA_ROOT, 'test_files')
 
 empty_number_tags_name = os.path.join(
     test_files, "reportsi_with_empty_number_tags.dcm")
diff --git a/pydicom/tests/test_pillow_pixel_data.py b/pydicom/tests/test_pillow_pixel_data.py
index d146ff169..3999e8d2e 100644
--- a/pydicom/tests/test_pillow_pixel_data.py
+++ b/pydicom/tests/test_pillow_pixel_data.py
@@ -4,6 +4,7 @@ import sys
 import pytest
 import pydicom
 from pydicom.filereader import read_file
+from pydicom.data import DATA_ROOT
 from pydicom.tag import Tag
 pillow_missing_message = ("pillow is not available "
                           "in this test environment")
@@ -32,9 +33,7 @@ test_pillow_jpeg_decoder = (test_pillow_decoder and
 test_pillow_jpeg2000_decoder = (test_pillow_decoder and
                                 have_pillow_jpeg2000_plugin)
 
-
-test_dir = os.path.dirname(__file__)
-test_files = os.path.join(test_dir, 'test_files')
+test_files = os.path.join(DATA_ROOT, 'test_files')
 
 empty_number_tags_name = os.path.join(
     test_files, "reportsi_with_empty_number_tags.dcm")
diff --git a/pydicom/tests/test_valuerep.py b/pydicom/tests/test_valuerep.py
index f20f3d614..e7eaade57 100644
--- a/pydicom/tests/test_valuerep.py
+++ b/pydicom/tests/test_valuerep.py
@@ -22,6 +22,7 @@ import platform
 from pydicom.compat import in_py2
 from pydicom import config
 from pydicom import valuerep
+from pydicom.data import DATA_ROOT
 import unittest
 
 have_dateutil = True
@@ -52,8 +53,7 @@ try:
 except ImportError:
     import pickle
 
-test_dir = os.path.dirname(__file__)
-test_files = os.path.join(test_dir, 'test_files')
+test_files = os.path.join(DATA_ROOT, 'test_files')
 badvr_name = os.path.join(test_files, "badVR.dcm")
 default_encoding = 'iso8859'