Repository: python-smpplib/python-smpplib (language: python)

Issue:
tests/ could be better packaged
Hey there, thanks for this software. I plan to lean on it soon :)

But if I `pip install smpplib` I end up with a top-level `tests` package that doesn't work:

```
$ python
Python 3.9.2 (default, Feb 20 2021, 18:40:11) 
[GCC 10.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import tests.test_gsm
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/kousu/.local/lib/python3.9/site-packages/tests/test_gsm.py", line 3, in <module>
    import mock
ModuleNotFoundError: No module named 'mock'
>>> 
```

You can see what actually got installed here:

```
$ ls ~/.local/lib/python3.9/site-packages/smpplib
client.py  command_codes.py  command.py  consts.py  exceptions.py  gsm.py  __init__.py	pdu.py	ptypes.py  __pycache__	smpp.py
$ ls ~/.local/lib/python3.9/site-packages/tests/
__init__.py  __pycache__  test_command.py  test_gsm.py
$ cat ~/.local/lib/python3.9/site-packages/smpplib-2.1.0.dist-info/RECORD 
smpplib-2.1.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
smpplib-2.1.0.dist-info/LICENSE,sha256=46mU2C5kSwOnkqkw9XQAJlhBL2JAf1_uCD8lVcXyMRg,7652
smpplib-2.1.0.dist-info/METADATA,sha256=m_PYPcJrG0NHJoKQnaW_LYNmeaefAQf5wDe7POXjWYU,4163
smpplib-2.1.0.dist-info/RECORD,,
smpplib-2.1.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
smpplib-2.1.0.dist-info/WHEEL,sha256=-ZFxwj8mZJPIVcZGLrsQ8UGRcxVAOExzPLVBGR7u7bE,92
smpplib-2.1.0.dist-info/top_level.txt,sha256=6f-00aSyR4s-yJi3vQMCBaYCDMMlD5NavUvr2K166U0,14
smpplib-2.1.0.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
smpplib/__init__.py,sha256=IsNibfXn_AXnYAZcRWM36cSLhNgGyLhMhHtLbNaZcuY,958
smpplib/__pycache__/__init__.cpython-39.pyc,,
smpplib/__pycache__/client.cpython-39.pyc,,
smpplib/__pycache__/command.cpython-39.pyc,,
smpplib/__pycache__/command_codes.cpython-39.pyc,,
smpplib/__pycache__/consts.cpython-39.pyc,,
smpplib/__pycache__/exceptions.cpython-39.pyc,,
smpplib/__pycache__/gsm.cpython-39.pyc,,
smpplib/__pycache__/pdu.cpython-39.pyc,,
smpplib/__pycache__/ptypes.cpython-39.pyc,,
smpplib/__pycache__/smpp.cpython-39.pyc,,
smpplib/client.py,sha256=Ag89el_XlQczaRdNyivu-YCOZpWxvl4YmB8A6h3NYwY,12510
smpplib/command.py,sha256=Xq01JDhV09Zd4K5tWuiAgjnodI9K-3_KWyg-9_yhkk8,33803
smpplib/command_codes.py,sha256=9cNJyROwQAFaTLwvm7BGMmm1b1UjuOdIeEjKLqX8EMM,1633
smpplib/consts.py,sha256=HLlobB8psWjlT14bknIVLUYrgK3IWznjrvpw8pTQsK8,13991
smpplib/exceptions.py,sha256=QIn2TX0XtYYS8sHdzGUKKTsRpqO3kdWl-ZaY62Zkiyk,311
smpplib/gsm.py,sha256=pG4DGHDX5cc-sHQYuW_lLMWgbt3i2Ce6aceepKqpRw8,3496
smpplib/pdu.py,sha256=FhkimxpJVbG25GHkuuRahIaSHJdFURY0QvA1hiD533g,4011
smpplib/ptypes.py,sha256=ryRmMQmXg9E8u6x6U2HaL2E_puQq7zeO3-DGoe9ZLt8,1108
smpplib/smpp.py,sha256=BAtb0SzNVu3qRM1zweRDalXja38p2rVazFTmEFVntNk,1317
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
tests/__pycache__/__init__.cpython-39.pyc,,
tests/__pycache__/test_command.cpython-39.pyc,,
tests/__pycache__/test_gsm.cpython-39.pyc,,
tests/test_command.py,sha256=glbsaDtrw9spTK3J3daAkz_yCvboid-HFy47bF_6bKI,1054
tests/test_gsm.py,sha256=vcRbSTz5pLLyc6RgmqsPzkbEXroSdWeuslu0RmYHnuo,2197
```

This is a known bug in python packaging that everyone has to work around, unfortunately:


* https://github.com/pypa/packaging.python.org/issues/320#issuecomment-495990983
* https://blog.ionelmc.ro/2014/05/25/python-packaging/#the-structure
* https://hynek.me/articles/testing-packaging/


I know of two workarounds, Either

1. Use `packages=find_packages(exclude=['tests'])` in 

    https://github.com/python-smpplib/python-smpplib/blob/29e611d20b21c4c6aff55ee867f2355f4c7085c8/setup.py#L12

    or maybe `packages=find_packages('smpplib/')`.

2. Switch to a `src/` layout (in the links above), with `mkdir src && git mv smpplib src && git mv tests src/smpplib` and then do 

    ```
    packages=find_packages('src/'])
    package_dir={"":"src/"},
    ```


Also, `tests_require` is deprecated (https://github.com/pypa/setuptools/issues/1684). The recommendation from on high is now to use `extras_require` like this (https://github.com/pypa/setuptools/issues/1684#issuecomment-648441338):

```
extras_require={
    'tests': ['pytest', 'mock', 'tox'],
    },
```

and then instead of 

https://github.com/python-smpplib/python-smpplib/blob/29e611d20b21c4c6aff55ee867f2355f4c7085c8/tox.ini#L6-L8

write

```
extras = tests
```


Discussion / hints:

Fix patch:
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 2343234..d7d80ca 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -22,17 +22,15 @@ jobs:
       - run:
           name: Install dependencies
           command: |
-            python -m venv venv || pypy -m venv venv || (
+            python -m venv venv || pypy -m venv venv || {
                 pip install virtualenv && virtualenv ./venv ||
-                virtualenv -p "$(which python || which pypy)" ./venv
-            )
-            . venv/bin/activate
-            pip install pytest mock
+                virtualenv -p "$(command -v python || command -v pypy)" ./venv;
+            }
       - run:
           name: Install project
           command: |
               . venv/bin/activate
-              pip install -e .
+              pip install -e .[tests]
       - run:
           name: Run tests
           command: |
diff --git a/setup.py b/setup.py
index 8940285..06ba978 100644
--- a/setup.py
+++ b/setup.py
@@ -2,18 +2,26 @@
 
 from setuptools import find_packages, setup
 
+try:
+    long_description_kwd=dict(
+        long_description=io.open('README.md', 'rt', encoding='utf-8').read(),
+        long_description_content_type='text/markdown',
+    )
+except OSError:
+    long_description_kwd=dict()
+
 setup(
     name='smpplib',
     version='2.1.0',
     url='https://github.com/podshumok/python-smpplib',
     description='SMPP library for python',
-    long_description=io.open('README.md', 'rt', encoding='utf-8').read(),
-    long_description_content_type='text/markdown',
     packages=find_packages(),
     install_requires=['six'],
-    tests_require=['pytest', 'mock', 'tox'],
+    extras_require=dict(
+        tests=('pytest', 'mock'),
+    ),
     zip_safe=True,
-    classifiers=[
+    classifiers=(
         'Development Status :: 5 - Production/Stable',
         'Intended Audience :: Telecommunications Industry',
         'License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)',
@@ -30,5 +38,6 @@
         'Topic :: Communications',
         'Topic :: Software Development :: Libraries :: Python Modules',
         'Topic :: Software Development :: Libraries',
-    ],
+    ),
+    **long_description_kwd
 )
diff --git a/tox.ini b/tox.ini
deleted file mode 100644
index 5e7bb6a..0000000
--- a/tox.ini
+++ /dev/null
@@ -1,8 +0,0 @@
-[tox]
-envlist = py26, py27, py34, py35, py36, py37
-
-[testenv]
-commands = pytest {posargs}
-deps =
-    pytest
-    mock


Test patch:
diff --git a/tests/__init__.py b/smpplib/tests/__init__.py
similarity index 100%
rename from tests/__init__.py
rename to smpplib/tests/__init__.py
diff --git a/tests/test_client.py b/smpplib/tests/test_client.py
similarity index 100%
rename from tests/test_client.py
rename to smpplib/tests/test_client.py
diff --git a/tests/test_command.py b/smpplib/tests/test_command.py
similarity index 100%
rename from tests/test_command.py
rename to smpplib/tests/test_command.py
diff --git a/tests/test_gsm.py b/smpplib/tests/test_gsm.py
similarity index 100%
rename from tests/test_gsm.py
rename to smpplib/tests/test_gsm.py