Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Autodetection library bugfixes, closes #82, #83 #85

Merged
merged 4 commits into from
Jan 4, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
Prospector Changelog
=======

## Version 0.8.2
* [#82](https://github.com/landscapeio/prospector/issues/82) resolves regression in adapter library detection raising, ``ValueError: too many values to unpack``. provided by [@jquast](https://github.com/jquast)
* [#83](https://github.com/landscapeio/prospector/issues/83) resolves regression when adapter library detects django, ``TypeError: '_sre.SRE_Pattern' object is not iterable``. provided by [@jquast](https://github.com/jquast)

## Version 0.8.1
* Strictness now also changes which pep257 messages are output
* pep257 and vulture messages are now combined and 'blended' with other tools
Expand Down
10 changes: 5 additions & 5 deletions prospector/autodetect.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
_FROM_IMPORT_REGEX = re.compile(r'^\s*from ([\._a-zA-Z0-9]+) import .*$')
_IMPORT_REGEX = re.compile(r'^\s*import ([\._a-zA-Z0-9]+)$')
_IMPORT_MULTIPLE_REGEX = re.compile(r'^\s*import ([\._a-zA-Z0-9]+(, ){1})+')
_CODING_REGEX = "coding[:=]\s*([-\w.]+)"
_CODING_REGEX = re.compile(r'coding[:=]\s*([-\w.]+)')


def detect_by_bom(path):
Expand All @@ -28,8 +28,8 @@ def detect_by_bom(path):
raw = fin.read(4)
for enc, boms in (
('utf-8-sig', (codecs.BOM_UTF8,)),
('utf-16', (codecs.BOM_UTF16_LE,codecs.BOM_UTF16_BE)),
('utf-32', (codecs.BOM_UTF32_LE,codecs.BOM_UTF32_BE))):
('utf-16', (codecs.BOM_UTF16_LE, codecs.BOM_UTF16_BE)),
('utf-32', (codecs.BOM_UTF32_LE, codecs.BOM_UTF32_BE))):
if any(raw.startswith(bom) for bom in boms):
return enc

Expand Down Expand Up @@ -117,8 +117,8 @@ def find_from_requirements(path):
reqs = find_requirements(path)
names = []
for requirement in reqs:
if requirement.name is not None \
and requirement.name.lower() in POSSIBLE_LIBRARIES:
if (requirement.name is not None
and requirement.name.lower() in POSSIBLE_LIBRARIES):
names.append(requirement.name.lower())
return names

Expand Down
9 changes: 5 additions & 4 deletions prospector/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,7 @@ def _find_used_libraries(self, config):

# Bring in adaptors that we automatically detect are needed
if config.autodetect:
for name, adaptor in autodetect_libraries(self.workdir):
libraries.append(name)
map(libraries.append, autodetect_libraries(self.workdir))

# Bring in adaptors for the specified libraries
for name in config.uses:
Expand Down Expand Up @@ -200,7 +199,9 @@ def _determine_ignores(self, config, profile, libraries):

# some libraries have further automatic ignores
if 'django' in libraries:
ignores += re.compile('(^|/)(south_)?migrations(/|$)')
ignores += [
re.compile('(^|/)(south_)?migrations(/|$)')
]

return ignores

Expand Down Expand Up @@ -258,4 +259,4 @@ def max_line_length(self):

@property
def loquacious_pylint(self):
return self.config.loquacious_pylint
return self.config.loquacious_pylint
42 changes: 32 additions & 10 deletions tests/test_autodetect.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,17 @@
import tempfile
import contextlib
from unittest import TestCase

from prospector.autodetect import find_from_imports, find_from_path
try:
from unittest.util import safe_repr
except ImportError:
# python2.6
safe_repr = repr

from prospector.autodetect import (
autodetect_libraries,
find_from_imports,
find_from_path,
)

class FindFromImportsTest(TestCase):

Expand Down Expand Up @@ -35,12 +44,15 @@ def test_multiple_imports(self):

def test_indented_imports(self):
""" django is discovered from function-local import statements. """
self._test('def lala(self):\n from django.db import models\n return models.Model', 'django')
self._test('def lala(self):\n'
'from django.db import models\n'
'return models.Model', 'django')

def test_same_line_two_imports(self):
""" importing two modules of interest on same line are discovered. """
self._test('import django, celery', 'django', 'celery')


class ImportCodingsTest(TestCase):

def SetUp(self):
Expand All @@ -51,7 +63,7 @@ def tearDown(self):
warnings.resetwarnings()
TestCase.tearDown(self)

if sys.version_info < (2,7):
if sys.version_info < (2, 7):
# backport assertGreaterEqual and assertIn for python2.6.

def assertGreaterEqual(self, a, b, msg=None):
Expand All @@ -67,7 +79,6 @@ def assertIn(self, member, container, msg=None):
safe_repr(container))
self.fail(self._formatMessage(msg, standardMsg))


@contextlib.contextmanager
def make_pypath(self, bindata):
tmp_folder = tempfile.mkdtemp(prefix='prospector-')
Expand All @@ -81,7 +92,6 @@ def make_pypath(self, bindata):
os.unlink(tmp_file)
os.rmdir(tmp_folder)


def test_latin1_coding_line2(self):
"""
File containing latin1 at line 2 with 'coding' declaration at line 1.
Expand All @@ -98,7 +108,6 @@ def test_latin1_coding_line2(self):
# verify.
self.assertEqual(set(expected_names), names)


def test_negative_latin1(self):
""" Negative test: file containing latin1 without 'coding' declaration. """
# given,
Expand All @@ -112,7 +121,6 @@ def test_negative_latin1(self):
self.assertGreaterEqual(len(warned), 1)
self.assertIn(ImportWarning, [_w.category for _w in warned])


def test_negative_lookuperror(self):
""" File declares an unknown coding. """
# given,
Expand All @@ -126,7 +134,6 @@ def test_negative_lookuperror(self):
self.assertGreaterEqual(len(warned), 1)
self.assertIn(ImportWarning, [_w.category for _w in warned])


def test_bom_encoded_filepath(self):
""" File containing only a UTF32_BE byte order mark still decodes. """
# given,
Expand All @@ -141,7 +148,6 @@ def test_bom_encoded_filepath(self):
# verify.
self.assertEqual(set(expected_names), names)


def test_negative_misleading_bom(self):
""" Negative test: file containing BOM that is not the correct encoding. """
# given,
Expand All @@ -157,6 +163,22 @@ def test_negative_misleading_bom(self):
self.assertIn(ImportWarning, [_w.category for _w in warned])


class AdaptersTest(TestCase):

""" Adapters detection requires a true project, we just use only our own. """

def test_autodetect_adapters_of_prospector(self):
""" Use prospector's base proj. folder, discovers nothing. """
# Given
tgt_path = os.path.join(os.path.dirname(__file__), os.path.pardir)

# Exercise
detected = autodetect_libraries(tgt_path)

# Verify
self.assertEqual(set(), detected)


if __name__ == '__main__':
import unittest
unittest.main()
6 changes: 4 additions & 2 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
[tox]
envlist = py26,py27,py33
envlist = py27,py33,py34

skip_missing_interpreters = true

[testenv]
deps =
nose
Django
commands = nosetests
commands = nosetests tests