summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEevee (Alex Munroe) <eevee.git@veekun.com>2013-07-26 14:37:04 -0700
committerEevee (Alex Munroe) <eevee.git@veekun.com>2013-07-26 14:37:04 -0700
commit84169485fa79b20d7dcb383260a768cd8d5603b0 (patch)
treec95ca63f2479385d6d0ad1e996c8397b7108dda4
parentbfd105152ed90bf4260a349be4c1a7717eb01911 (diff)
downloadpyscss-84169485fa79b20d7dcb383260a768cd8d5603b0.tar.gz
Split up importing logic.
- Less nesting! - IO errors are now propagated out rather than turning into warnings. - SASS imports are supported. - Duplicate names that refer to different files (due to relative importing) should now work. - Closer to pluggable importing.
-rw-r--r--scss/__init__.py138
1 files changed, 70 insertions, 68 deletions
diff --git a/scss/__init__.py b/scss/__init__.py
index 3b3028f..71827f5 100644
--- a/scss/__init__.py
+++ b/scss/__init__.py
@@ -47,6 +47,7 @@ __license__ = LICENSE
from collections import defaultdict, deque
import glob
+from itertools import product
import logging
import os.path
import re
@@ -772,78 +773,79 @@ class Scss(object):
# If already imported in this scope, skip
continue
- unsupported = []
- load_paths = []
- filename = os.path.basename(name)
- dirname = os.path.dirname(name)
+ full_filename, seen_paths = self._find_import(rule, name)
+
+ if full_filename is None:
+ i_codestr = self._do_magic_import(rule, p_children, scope, block)
- source_file = None
- try:
- source_file = self.source_file_index[name]
- except KeyError:
- i_codestr = None
-
- for path in self.search_paths:
- for basepath in [rule.source_file.parent_dir, '.']:
- i_codestr = None
- full_path = os.path.realpath(os.path.join(basepath, path, dirname))
- if full_path in load_paths:
- continue
- try:
- full_filename = os.path.join(full_path, '_' + filename)
- i_codestr = open(full_filename + '.scss').read()
- full_filename += '.scss'
- except IOError:
- if os.path.exists(full_filename + '.sass'):
- unsupported.append(full_filename + '.sass')
- try:
- full_filename = os.path.join(full_path, filename)
- i_codestr = open(full_filename + '.scss').read()
- full_filename += '.scss'
- except IOError:
- if os.path.exists(full_filename + '.sass'):
- unsupported.append(full_filename + '.sass')
- try:
- full_filename = os.path.join(full_path, '_' + filename)
- i_codestr = open(full_filename).read()
- except IOError:
- try:
- full_filename = os.path.join(full_path, filename)
- i_codestr = open(full_filename).read()
- except IOError:
- pass
- if i_codestr is not None:
- break
- else:
- load_paths.append(full_path)
- if i_codestr is not None:
- break
- if i_codestr is None:
- i_codestr = self._do_magic_import(rule, p_children, scope, block)
if i_codestr is not None:
- source_file = SourceFile(full_filename, i_codestr, parent_dir=os.path.dirname(full_filename))
- self.source_files.append(source_file)
- self.source_file_index[name] = source_file
- if source_file is None:
- load_paths = load_paths and "\nLoad paths:\n\t%s" % "\n\t".join(load_paths) or ''
- unsupported = unsupported and "\nPossible matches (for unsupported file format SASS):\n\t%s" % "\n\t".join(unsupported) or ''
- log.warn("File to import not found or unreadable: '%s' (%s)%s%s", filename, rule.file_and_line, load_paths, unsupported)
+ source_file = SourceFile.from_string(i_codestr)
+
+ elif full_filename in self.source_file_index:
+ source_file = self.source_file_index[full_filename]
+
else:
- _rule = SassRule(
- source_file=source_file,
- lineno=block.lineno,
- unparsed_contents=source_file.contents,
-
- # rule
- #dependent_rules
- options=rule.options,
- properties=rule.properties,
- extends_selectors=rule.extends_selectors,
- ancestry=rule.ancestry,
- namespace=rule.namespace,
+ with open(full_filename) as f:
+ source = f.read()
+ source_file = SourceFile(
+ full_filename,
+ source,
+ parent_dir=os.path.dirname(full_filename),
)
- self.manage_children(_rule, p_children, scope)
- rule.options[import_key] = True
+
+ self.source_files.append(source_file)
+ self.source_file_index[full_filename] = source_file
+
+ if source_file is None:
+ load_paths_msg = "\nLoad paths:\n\t%s" % "\n\t".join(seen_paths)
+ log.warn("File to import not found or unreadable: '%s' (%s)%s", name, rule.file_and_line, load_paths_msg)
+ continue
+
+ _rule = SassRule(
+ source_file=source_file,
+ lineno=block.lineno,
+ unparsed_contents=source_file.contents,
+
+ # rule
+ #dependent_rules
+ options=rule.options,
+ properties=rule.properties,
+ extends_selectors=rule.extends_selectors,
+ ancestry=rule.ancestry,
+ namespace=rule.namespace,
+ )
+ self.manage_children(_rule, p_children, scope)
+ rule.options[import_key] = True
+
+ def _find_import(self, rule, name):
+ """Find the file referred to by an @import.
+
+ Takes a name from an @import and returns an absolute path, or None.
+ """
+ name, ext = os.path.splitext(name)
+ if ext:
+ search_exts = [ext]
+ else:
+ search_exts = ['.scss', '.sass']
+
+ dirname, name = os.path.split(name)
+
+ seen_paths = []
+
+ for path in self.search_paths:
+ for basepath in [rule.source_file.parent_dir, '.']:
+ full_path = os.path.realpath(os.path.join(basepath, path, dirname))
+
+ if full_path in seen_paths:
+ continue
+ seen_paths.append(full_path)
+
+ for prefix, suffix in product(('_', ''), search_exts):
+ full_filename = os.path.join(full_path, prefix + name + suffix)
+ if os.path.exists(full_filename):
+ return full_filename, seen_paths
+
+ return None, seen_paths
@print_timing(10)
def _do_magic_import(self, rule, p_children, scope, block):