Browse Source

Initial support for Python 3

David Cramer 8 years ago
parent
commit
461204944f
10 changed files with 36 additions and 22 deletions
  1. 2 0
      .travis.yml
  2. 1 1
      Makefile
  3. 6 5
      api-docs/generator.py
  4. 1 1
      api-docs/sentry.conf.py
  5. 1 1
      bin/dump-command-help
  6. 3 1
      bin/load-mocks
  7. 5 1
      config/hooks/pre-commit
  8. 12 10
      setup.py
  9. 1 0
      src/sentry/__main__.py
  10. 4 2
      src/sentry/admin.py

+ 2 - 0
.travis.yml

@@ -11,6 +11,8 @@ services:
   - cassandra
 python:
   - "2.7"
+  # - "3.4"
+  # - "3.5"
 cache:
   directories:
     - node_modules

+ 1 - 1
Makefile

@@ -172,7 +172,7 @@ travis-install-mysql: travis-install-python
 travis-install-acceptance: install-npm travis-install-postgres
 travis-install-js: travis-upgrade-pip install-python install-python-tests install-npm
 travis-install-cli: travis-install-python
-travis-install-dist: travis-noop
+travis-install-dist: travis-install-python
 
 .PHONY: travis-install-sqlite travis-install-postgres travis-install-js travis-install-cli travis-install-dist
 

+ 6 - 5
api-docs/generator.py

@@ -4,12 +4,13 @@ import os
 import zlib
 import json
 import click
-import urlparse
 import logging
+import six
 
 from datetime import datetime
 from subprocess import Popen, PIPE
 from contextlib import contextmanager
+from six.moves.urllib.parse import urlparse
 
 HERE = os.path.abspath(os.path.dirname(__file__))
 SENTRY_CONFIG = os.environ['SENTRY_CONF'] = os.path.join(HERE, 'sentry.conf.py')
@@ -28,7 +29,7 @@ from sentry.utils.apidocs import Runner, MockUtils, iter_scenarios, \
 
 
 OUTPUT_PATH = os.path.join(HERE, 'cache')
-HOST = urlparse.urlparse(settings.SENTRY_OPTIONS['system.url-prefix']).netloc
+HOST = urlparse(settings.SENTRY_OPTIONS['system.url-prefix']).netloc
 
 
 # We don't care about you, go away
@@ -45,7 +46,7 @@ def report(category, message, fg=None):
     if fg is None:
         fg = color_for_string(category)
     click.echo('[%s] %s: %s' % (
-        str(datetime.utcnow()).split('.')[0],
+        six.text_type(datetime.utcnow()).split('.')[0],
         click.style(category, fg=fg),
         message
     ))
@@ -59,7 +60,7 @@ def launch_redis():
     databases %(databases)d
     save ""
     ''' % {
-        'port': str(settings.SENTRY_APIDOCS_REDIS_PORT),
+        'port': six.text_type(settings.SENTRY_APIDOCS_REDIS_PORT),
         'databases': 4,
     })
     cl.stdin.flush()
@@ -210,7 +211,7 @@ def cli(output_path):
             'sections': dict((section, {
                 'title': title,
                 'entries': dict(section_mapping.get(section, ())),
-            }) for section, title in get_sections().iteritems())
+            }) for section, title in six.iteritems(get_sections()))
         })
 
 

+ 1 - 1
api-docs/sentry.conf.py

@@ -52,7 +52,7 @@ SENTRY_WEB_OPTIONS = {
 SENTRY_OPTIONS.update({
     'redis.clusters': {
         'default': {
-            'hosts': {i: {'port': SENTRY_APIDOCS_REDIS_PORT} for i in xrange(0, 4)},
+            'hosts': {i: {'port': SENTRY_APIDOCS_REDIS_PORT} for i in range(0, 4)},
         },
     },
     'system.secret-key': 'super secret secret key',

+ 1 - 1
bin/dump-command-help

@@ -97,7 +97,7 @@ def dump_command(out, cmd, path):
             })
 
     if isinstance(cmd, click.Group):
-        for child_name, child_cmd in cmd.commands.iteritems():
+        for child_name, child_cmd in six.iteritems(cmd.commands):
             dump_command(out, child_cmd, path + [child_name])
             data['subcommands'].append(child_name)
 

+ 3 - 1
bin/load-mocks

@@ -3,6 +3,7 @@ from sentry.runner import configure
 configure()
 
 import itertools
+import six
 
 from datetime import datetime, timedelta
 from django.conf import settings
@@ -20,6 +21,7 @@ from sentry.models import (
     OrganizationMember, Project, Release, ReleaseFile, Team, User, UserReport,
     GroupRelease, Environment, ReleaseEnvironment
 )
+from sentry.utils.hashlib import sha1, md5
 from sentry.utils.samples import create_sample_event
 
 PLATFORMS = itertools.cycle([
@@ -298,7 +300,7 @@ def main(num_events=1):
                     level=LEVELS.next(),
                     environment=ENVIRONMENTS.next(),
                     message='This is a mostly useless example %s exception' % platform,
-                    checksum=md5(platform + str(_)).hexdigest(),
+                    checksum=md5(platform + six.text_type(_)).hexdigest(),
                 )
 
             for _ in range(num_events):

+ 5 - 1
config/hooks/pre-commit

@@ -23,7 +23,11 @@ def main():
 
     _, files_modified, _ = run(gitcmd)
 
-    files_modified = filter(lambda x: os.path.exists(x), files_modified)
+    files_modified = [
+        f
+        for f in files_modified
+        if os.path.exists(f)
+    ]
 
     return check_files(files_modified)
 

+ 12 - 10
setup.py

@@ -26,9 +26,9 @@ from __future__ import absolute_import
 
 import sys
 
-if sys.version_info[:2] != (2, 7):
-    print 'Error: Sentry requires Python 2.7'
-    sys.exit(1)
+# if sys.version_info[:2] != (2, 7):
+#     print 'Error: Sentry requires Python 2.7'
+#     sys.exit(1)
 
 import os
 import json
@@ -68,7 +68,7 @@ IS_LIGHT_BUILD = os.environ.get('SENTRY_LIGHT_BUILD') == '1'
 
 dev_requires = [
     'Babel',
-    'flake8>=2.1,<2.2',
+    'flake8>=2.6,<2.7',
     'pycodestyle>=2.0,<2.1',
     'isort>=4.2.2,<4.3.0',
 ]
@@ -88,9 +88,9 @@ tests_require = [
 
 
 install_requires = [
-    'BeautifulSoup>=3.2.1,<3.3.0',
     'celery>=3.1.8,<3.1.19',
     'click>=5.0,<7.0',
+    # 'cryptography>=1.3,<1.4',
     'cssutils>=0.9.9,<0.10.0',
     'Django>=1.6.0,<1.7',
     'django-bitfield>=1.7.0,<1.8.0',
@@ -105,16 +105,18 @@ install_requires = [
     'email-reply-parser>=0.2.0,<0.3.0',
     'enum34>=0.9.18,<1.2.0',
     'exam>=0.5.1',
+    # broken on python3
     'hiredis>=0.1.0,<0.2.0',
     'honcho>=0.7.0,<0.8.0',
-    'ipaddr>=2.1.11,<2.2.0',
     'kombu==3.0.35',
     'lxml>=3.4.1',
+
+    'ipaddress>=1.0.16,<1.1.0',
     'mock>=0.8.0,<1.1',
     'oauth2>=1.5.167',
     'petname>=1.7,<1.8',
     'Pillow>=3.2.0,<3.3.0',
-    'progressbar>=2.2,<2.4',
+    'progressbar2>=3.10,<3.11',
     'psycopg2>=2.6.0,<2.7.0',
     'pytest>=2.6.4,<2.7.0',
     'pytest-django>=2.9.1,<2.10.0',
@@ -122,13 +124,13 @@ install_requires = [
     'python-dateutil>=2.0.0,<3.0.0',
     'python-memcached>=1.53,<2.0.0',
     'python-openid>=2.2',
-    'PyYAML>=3.11,<4.0',
+    'PyYAML>=3.11,<3.12',
     'raven>=5.21.0,<6.0.0',
     'redis>=2.10.3,<2.11.0',
-    'requests%s>=2.9.1,<2.11.0' % (not IS_LIGHT_BUILD and '[security]' or ''),
+    'requests[security]>=2.9.1,<2.11.0',
     'selenium>=2.53,<2.60',
     'simplejson>=3.2.0,<3.9.0',
-    'six>=1.6.0,<2.0.0',
+    'six>=1.10.0,<1.11.0',
     'setproctitle>=1.1.7,<1.2.0',
     'statsd>=3.1.0,<3.2.0',
     'structlog==16.1.0',

+ 1 - 0
src/sentry/__main__.py

@@ -5,6 +5,7 @@ sentry
 :copyright: (c) 2015 by the Sentry Team, see AUTHORS for more details.
 :license: BSD, see LICENSE for more details.
 """
+from __future__ import absolute_import
 
 from .runner import main
 main()

+ 4 - 2
src/sentry/admin.py

@@ -8,7 +8,6 @@ from django.contrib.auth.forms import (
 from django.core.exceptions import PermissionDenied
 from django.db import transaction
 from django.http import Http404, HttpResponseRedirect
-from django.utils.html import escape
 from django.utils.decorators import method_decorator
 from django.views.decorators.csrf import csrf_protect
 from django.views.decorators.debug import sensitive_post_parameters
@@ -21,6 +20,7 @@ from sentry.models import (
     Option, Organization, OrganizationMember, OrganizationMemberTeam, Project,
     Team, User
 )
+from sentry.utils.html import escape
 
 csrf_protect_m = method_decorator(csrf_protect)
 sensitive_post_parameters_m = method_decorator(sensitive_post_parameters())
@@ -42,7 +42,9 @@ class OptionAdmin(admin.ModelAdmin):
     search_fields = ('key',)
 
     def value_repr(self, instance):
-        return '<pre style="display:inline-block;white-space:pre-wrap;">{}</pre>'.format(escape(saferepr(instance.value)))
+        return '<pre style="display:inline-block;white-space:pre-wrap;">{}</pre>'.format(
+            escape(saferepr(instance.value))
+        )
 
     value_repr.short_description = "Value"
     value_repr.allow_tags = True

Some files were not shown because too many files changed in this diff