Skip to content

Commit dde73cb

Browse files
authored
Merge pull request #369 from nexB/test-cleanup
Improve tests and other refactorings
2 parents 4e906ae + b3ed23f commit dde73cb

File tree

376 files changed

+5053
-4074
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

376 files changed

+5053
-4074
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,5 @@ docs/_build
4747
/.cache/
4848
/.settings/
4949
/tcl/
50+
/.python-version
51+
/.tox/

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ install:
88
- ./configure etc/conf/dev
99

1010
script:
11-
- bin/py.test -vvs tests
11+
- bin/py.test -vvs
1212

1313
notifications:
1414
irc:

about.cfg

Lines changed: 0 additions & 35 deletions
This file was deleted.

etc/scripts/irc-notify.py.ABOUT

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1+
about_resource: irc-notify.py
12
name: irc-notify.py
23
version: def54f8166089b733d166665fdabcad4cdc526d8
34
download_url: https://raw.githubusercontent.com/gridsync/gridsync/def54f8166089b733d166665fdabcad4cdc526d8/misc/irc-notify.py
45
description: Quick and dirty IRC notification script.
56
homepage_url: https://github.com/gridsync/gridsync
67
owner: Christopher R. Wood
78
copyright: Copyright (C) 2015-2016 Christopher R. Wood
8-
dje_license_key: gpl-2.0-plus
9+
license_expression: gpl-2.0-plus
910
license_text_file: gpl-2.0.LICENSE
1011
notice_text: |
1112
This program is free software; you can redistribute it and/or modify it under the

setup.cfg

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,23 @@ release = clean --all sdist --formats=bztar,zip bdist_wheel
1010
[tool:pytest]
1111
norecursedirs =
1212
.git
13+
.cache
14+
.settings
1315
bin
1416
dist
17+
dist
1518
build
1619
_build
17-
dist
18-
local
19-
ci
2020
docs
2121
man
2222
share
23-
samples
24-
.cache
25-
.settings
23+
example
2624
etc
2725
Include
2826
include
2927
Lib
3028
lib
29+
local
3130
Scripts
3231
thirdparty
3332
tmp

setup.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,15 @@ def read(*names, **kwargs):
6868
],
6969
install_requires=[
7070
'jinja2 >= 2.9, < 3.0',
71+
7172
'click >= 6.7, < 7.0',
73+
7274
"backports.csv ; python_version<'3.6'",
73-
'PyYAML >= 3.0, < 4.0',
75+
76+
# required by saneyaml
77+
'PyYAML >= 3.11, <=3.13',
78+
'saneyaml',
79+
7480
'boolean.py >= 3.5, < 4.0',
7581
'license_expression >= 0.94, < 1.0',
7682
],
@@ -79,7 +85,7 @@ def read(*names, **kwargs):
7985
},
8086
entry_points={
8187
'console_scripts': [
82-
'about=attributecode.cmd:cli',
88+
'about=attributecode.cmd:about',
8389
]
8490
},
8591
)

src/attributecode/__init__.py

Lines changed: 47 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,19 @@
2020

2121
from collections import namedtuple
2222
import logging
23+
import os
2324

2425
try:
25-
unicode # Python 2
26-
except NameError:
27-
unicode = str # Python 3 #NOQA
26+
# Python 2
27+
unicode # NOQA
28+
except NameError: # pragma: nocover
29+
# Python 3
30+
unicode = str # NOQA
2831

32+
import saneyaml
2933

3034
__version__ = '3.3.0'
3135

32-
3336
__about_spec_version__ = '3.1'
3437

3538
__copyright__ = """
@@ -53,39 +56,46 @@ class Error(namedtuple('Error', ['severity', 'message'])):
5356
def __new__(self, severity, message):
5457
if message:
5558
if isinstance(message, unicode):
56-
message = clean_string(message)
59+
message = self._clean_string(message)
5760
else:
58-
message = clean_string(unicode(repr(message), encoding='utf-8'))
61+
message = self._clean_string(unicode(repr(message), encoding='utf-8'))
5962
message = message.strip('"')
6063

6164
return super(Error, self).__new__(
6265
Error, severity, message)
6366

6467
def __repr__(self, *args, **kwargs):
6568
sev = severities[self.severity]
66-
msg = clean_string(repr(self.message))
69+
msg = self._clean_string(repr(self.message))
6770
return 'Error(%(sev)s, %(msg)s)' % locals()
6871

69-
70-
def clean_string(s):
71-
"""
72-
Return a cleaned string for `s`, stripping eventual "u" prefixes
73-
from unicode representations.
74-
"""
75-
if not s:
72+
def to_dict(self, *args, **kwargs):
73+
"""
74+
Return an ordered mapping of self.
75+
"""
76+
return self._asdict()
77+
78+
@staticmethod
79+
def _clean_string(s):
80+
"""
81+
Return a cleaned string for `s`, stripping eventual "u" prefixes
82+
from unicode representations.
83+
"""
84+
if not s:
85+
return s
86+
if s.startswith(('u"', "u'")):
87+
s = s.lstrip('u')
88+
s = s.replace('[u"', '["')
89+
s = s.replace("[u'", "['")
90+
s = s.replace("(u'", "('")
91+
s = s.replace("(u'", "('")
92+
s = s.replace("{u'", "{'")
93+
s = s.replace("{u'", "{'")
94+
s = s.replace(" u'", " '")
95+
s = s.replace(" u'", " '")
96+
s = s.replace("\\\\", "\\")
7697
return s
77-
if s.startswith(('u"', "u'")):
78-
s = s.lstrip('u')
79-
s = s.replace('[u"', '["')
80-
s = s.replace("[u'", "['")
81-
s = s.replace("(u'", "('")
82-
s = s.replace("(u'", "('")
83-
s = s.replace("{u'", "{'")
84-
s = s.replace("{u'", "{'")
85-
s = s.replace(" u'", " '")
86-
s = s.replace(" u'", " '")
87-
s = s.replace("\\\\", "\\")
88-
return s
98+
8999

90100
# modeled after the logging levels
91101
CRITICAL = 50
@@ -97,10 +107,14 @@ def clean_string(s):
97107

98108

99109
severities = {
100-
CRITICAL : u'CRITICAL',
101-
ERROR : u'ERROR',
102-
WARNING : u'WARNING',
103-
INFO : u'INFO',
104-
DEBUG : u'DEBUG',
105-
NOTSET : u'NOTSET'
106-
}
110+
CRITICAL : 'CRITICAL',
111+
ERROR : 'ERROR',
112+
WARNING : 'WARNING',
113+
INFO : 'INFO',
114+
DEBUG : 'DEBUG',
115+
NOTSET : 'NOTSET'
116+
}
117+
118+
119+
DEFAULT_MAPPING = os.path.join(os.path.abspath(
120+
os.path.dirname(__file__)), 'mapping.config')

src/attributecode/__main__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,6 @@
1919
from __future__ import unicode_literals
2020

2121

22-
if __name__ == '__main__':
22+
if __name__ == '__main__': # pragma: nocover
2323
from attributecode import cmd
2424
cmd.cli()

src/attributecode/api.py

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,28 +20,35 @@
2020

2121
import json
2222

23-
try: # Python 2
24-
from urllib import urlencode, quote
25-
from urllib2 import urlopen, Request, HTTPError
26-
except ImportError: # Python 3
27-
from urllib.parse import urlencode, quote
28-
from urllib.request import urlopen, Request
29-
from urllib.error import HTTPError
30-
3123
from attributecode import ERROR
3224
from attributecode import Error
25+
from attributecode.util import python2
26+
27+
28+
if python2: # pragma: nocover
29+
from urllib import quote # NOQA
30+
from urllib import urlencode # NOQA
31+
from urllib2 import HTTPError # NOQA
32+
from urllib2 import Request # NOQA
33+
from urllib2 import urlopen # NOQA
34+
else: # pragma: nocover
35+
from urllib.parse import quote # NOQA
36+
from urllib.parse import urlencode # NOQA
37+
from urllib.request import Request # NOQA
38+
from urllib.request import urlopen # NOQA
39+
from urllib.error import HTTPError # NOQA
3340

3441

3542
"""
3643
API call helpers
3744
"""
3845

3946

40-
def request_license_data(url, api_key, license_key):
47+
# FIXME: args should start with license_key
48+
def request_license_data(api_url, api_key, license_key):
4149
"""
42-
Return a dictionary of license data.
43-
Send a request to a given API URL to gather license data for
44-
license_key, authenticating through an api_key.
50+
Return a tuple of (dictionary of license data, list of errors) given a
51+
`license_key`. Send a request to `api_url` authenticating with `api_key`.
4552
"""
4653
headers = {
4754
'Authorization': 'Token %s' % api_key,
@@ -52,9 +59,10 @@ def request_license_data(url, api_key, license_key):
5259
'format': 'json'
5360
}
5461

55-
url = url.rstrip('/')
56-
encoded_payload = urlencode(payload)
57-
full_url = '%(url)s/?%(encoded_payload)s' % locals()
62+
api_url = api_url.rstrip('/')
63+
payload = urlencode(payload)
64+
65+
full_url = '%(api_url)s/?%(payload)s' % locals()
5866
# handle special characters in URL such as space etc.
5967
quoted_url = quote(full_url, safe="%/:=&?~#+!$,;'@()*[]")
6068

@@ -64,10 +72,12 @@ def request_license_data(url, api_key, license_key):
6472
request = Request(quoted_url, headers=headers)
6573
response = urlopen(request)
6674
response_content = response.read().decode('utf-8')
75+
# FIXME: this should be an ordered dict
6776
license_data = json.loads(response_content)
6877
if not license_data['results']:
6978
msg = u"Invalid 'license': %s" % license_key
7079
errors.append(Error(ERROR, msg))
80+
7181
except HTTPError as http_e:
7282
# some auth problem
7383
if http_e.code == 403:
@@ -80,20 +90,29 @@ def request_license_data(url, api_key, license_key):
8090
# this exception.
8191
msg = u"Invalid 'license': %s" % license_key
8292
errors.append(Error(ERROR, msg))
93+
8394
except Exception as e:
8495
errors.append(Error(ERROR, str(e)))
96+
8597
finally:
86-
license_data = license_data.get('results')[0] if license_data.get('count') == 1 else {}
98+
if license_data.get('count') == 1:
99+
license_data = license_data.get('results')[0]
100+
else:
101+
license_data = {}
87102

88103
return license_data, errors
89104

90105

91-
def get_license_details_from_api(url, api_key, license_key):
106+
# FIXME: args should start with license_key
107+
def get_license_details_from_api(api_url, api_key, license_key):
92108
"""
93-
Return the license_text of a given license_key using an API request.
94-
Return an empty string if the text is not available.
109+
Return a tuple of license data given a `license_key` using the `api_url`
110+
authenticating with `api_key`.
111+
The details are a tuple of (license_name, license_key, license_text, errors)
112+
where errors is a list of strings.
113+
Missing values are provided as empty strings.
95114
"""
96-
license_data, errors = request_license_data(url, api_key, license_key)
115+
license_data, errors = request_license_data(api_url, api_key, license_key)
97116
license_name = license_data.get('name', '')
98117
license_text = license_data.get('full_text', '')
99118
license_key = license_data.get('key', '')

0 commit comments

Comments
 (0)