Repository: praw-dev/praw
Pull request #502 (2015-08-23 19:39:01)

Refactor UA string usage.


Patch:
diff --git a/praw/__init__.py b/praw/__init__.py
index b2e8a535..7882cda2 100644
--- a/praw/__init__.py
+++ b/praw/__init__.py
@@ -52,20 +52,6 @@ from warnings import warn_explicit
 
 __version__ = '3.2.1'
 
-if os.environ.get('SERVER_SOFTWARE') is not None:
-    # Google App Engine information
-    # https://developers.google.com/appengine/docs/python/
-    PLATFORM_INFO = os.environ.get('SERVER_SOFTWARE')
-else:
-    # Standard platform information
-    PLATFORM_INFO = platform.platform(True)
-
-PLATFORM_INFO = ''.join(i for i in PLATFORM_INFO if ord(i) < 128)
-
-UA_STRING = '%%s PRAW/%s Python/%s %s' % (__version__,
-                                          sys.version.split()[0],
-                                          PLATFORM_INFO)
-
 MIN_IMAGE_SIZE = 128
 MAX_IMAGE_SIZE = 512000
 JPEG_HEADER = b'\xff\xd8\xff'
@@ -205,6 +191,24 @@ class Config(object):  # pylint: disable=R0903
                  'wiki_contributors':   'r/%s/about/wikicontributors/'}
     WWW_PATHS = set(['authorize'])
 
+    @staticmethod
+    def ua_string(praw_info):
+        """Return the user-agent string.
+
+        The user-agent string contains PRAW version and platform version info.
+
+        """
+        if os.environ.get('SERVER_SOFTWARE') is not None:
+            # Google App Engine information
+            # https://developers.google.com/appengine/docs/python/
+            info = os.environ.get('SERVER_SOFTWARE')
+        else:
+            # Standard platform information
+            info = platform.platform(True).encode('ascii', 'ignore')
+
+        return '{0} PRAW/{1} Python/{2} {3}'.format(
+            praw_info, __version__, sys.version.split()[0], info)
+
     def __init__(self, site_name, **kwargs):
         """Initialize PRAW's configuration."""
         def config_boolean(item):
@@ -254,7 +258,7 @@ class Config(object):  # pylint: disable=R0903
         self.refresh_token = obj.get('oauth_refresh_token') or None
         self.store_json_result = config_boolean(obj.get('store_json_result'))
 
-        if 'short_domain' in obj:
+        if 'short_domain' in obj and obj['short_domain']:
             self._short_domain = 'http://' + obj['short_domain']
         else:
             self._short_domain = None
@@ -335,7 +339,7 @@ class BaseReddit(object):
                              **kwargs)
         self.handler = handler or DefaultHandler()
         self.http = Session()
-        self.http.headers['User-Agent'] = UA_STRING % user_agent
+        self.http.headers['User-Agent'] = self.config.ua_string(user_agent)
         self.http.validate_certs = self.config.validate_certs
 
         # This `Session` object is only used to store request information that
diff --git a/praw/praw.ini b/praw/praw.ini
index 37cf00d9..e4828c87 100644
--- a/praw/praw.ini
+++ b/praw/praw.ini
@@ -71,5 +71,6 @@ api_request_delay: 0
 log_requests: 0
 message_kind: t7
 permalink_domain: reddit.local
+short_domain:
 submission_kind: t6
 subreddit_kind: t5


Test patch:
diff --git a/tests/test_config.py b/tests/test_config.py
new file mode 100644
index 00000000..08ab196f
--- /dev/null
+++ b/tests/test_config.py
@@ -0,0 +1,42 @@
+"""Tests for Config class."""
+
+from __future__ import print_function, unicode_literals
+
+import unittest
+from praw import Config
+from praw.errors import ClientException
+
+try:
+    import ConfigParser as configparser
+except ImportError:
+    import configparser  # NOQA pylint: disable=F0401
+
+
+class ConfigTest(unittest.TestCase):
+    def test_default_site(self):
+        config = Config('reddit')
+        self.assertEqual(0, config.log_requests)
+        self.assertEqual(2, config.api_request_delay)
+        self.assertEqual(None, config.user)
+        self.assertEqual(None, config.pswd)
+
+    def test_default_site__with_overrides(self):
+        config = Config('reddit', log_requests=15, api_request_delay=21)
+        self.assertEqual(15, config.log_requests)
+        self.assertEqual(21, config.api_request_delay)
+
+    def test_default_site__with_username_and_password(self):
+        config = Config('reddit', user='foo', pswd='bar')
+        self.assertEqual('foo', config.user)
+        self.assertEqual('bar', config.pswd)
+
+    def test_invalid_site(self):
+        self.assertRaises(configparser.NoSectionError, Config, 'invalid')
+
+    def test_local_site(self):
+        config = Config('local_example')
+        try:
+            config.short_domain
+            self.fail('Did not raise ClientException')
+        except ClientException:
+            pass