Import Upstream version 0.22.0
This commit is contained in:
parent
be11e18fcc
commit
f81cc0bca9
|
@ -6,7 +6,6 @@
|
||||||
.*.swp
|
.*.swp
|
||||||
.DS_Store
|
.DS_Store
|
||||||
._.DS_Store
|
._.DS_Store
|
||||||
.pytest_cache/
|
|
||||||
.coverage
|
.coverage
|
||||||
.tox
|
.tox
|
||||||
/.libsass-upstream-version
|
/.libsass-upstream-version
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
[submodule "libsass"]
|
[submodule "libsass"]
|
||||||
path = libsass
|
path = libsass
|
||||||
url = git://github.com/sass/libsass.git
|
url = https://github.com/sass/libsass
|
||||||
|
|
|
@ -1,21 +1,35 @@
|
||||||
repos:
|
repos:
|
||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
rev: v4.0.1
|
rev: v4.3.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: trailing-whitespace
|
- id: trailing-whitespace
|
||||||
- id: end-of-file-fixer
|
- id: end-of-file-fixer
|
||||||
- id: check-yaml
|
- id: check-yaml
|
||||||
- id: debug-statements
|
- id: debug-statements
|
||||||
|
- id: double-quote-string-fixer
|
||||||
|
- id: name-tests-test
|
||||||
|
- id: requirements-txt-fixer
|
||||||
|
- repo: https://github.com/asottile/reorder_python_imports
|
||||||
|
rev: v3.8.5
|
||||||
|
hooks:
|
||||||
|
- id: reorder-python-imports
|
||||||
|
args: [--py36-plus]
|
||||||
|
- repo: https://github.com/asottile/add-trailing-comma
|
||||||
|
rev: v2.3.0
|
||||||
|
hooks:
|
||||||
|
- id: add-trailing-comma
|
||||||
|
args: [--py36-plus]
|
||||||
|
- repo: https://github.com/asottile/pyupgrade
|
||||||
|
rev: v3.1.0
|
||||||
|
hooks:
|
||||||
|
- id: pyupgrade
|
||||||
|
args: [--py36-plus]
|
||||||
|
- repo: https://github.com/pre-commit/mirrors-autopep8
|
||||||
|
rev: v1.7.0
|
||||||
|
hooks:
|
||||||
|
- id: autopep8
|
||||||
- repo: https://github.com/PyCQA/flake8
|
- repo: https://github.com/PyCQA/flake8
|
||||||
rev: 3.9.2
|
rev: 5.0.4
|
||||||
hooks:
|
hooks:
|
||||||
- id: flake8
|
- id: flake8
|
||||||
exclude: ^docs/conf.py
|
exclude: ^docs/conf.py
|
||||||
- repo: https://github.com/asottile/pyupgrade
|
|
||||||
rev: v2.16.0
|
|
||||||
hooks:
|
|
||||||
- id: pyupgrade
|
|
||||||
- repo: https://github.com/asottile/add-trailing-comma
|
|
||||||
rev: v2.1.0
|
|
||||||
hooks:
|
|
||||||
- id: add-trailing-comma
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ Tests
|
||||||
- All commits will be tested by `Azure Pipelines`_ (Linux and Windows).
|
- All commits will be tested by `Azure Pipelines`_ (Linux and Windows).
|
||||||
|
|
||||||
.. _tox: https://tox.readthedocs.io/
|
.. _tox: https://tox.readthedocs.io/
|
||||||
.. _`Azure Pipelines`: https://dev.azure.com/asottile/asottile/_build/latest?definitionId=22&branchName=master
|
.. _`Azure Pipelines`: https://dev.azure.com/asottile/asottile/_build/latest?definitionId=22&branchName=main
|
||||||
|
|
||||||
|
|
||||||
Maintainer's guide
|
Maintainer's guide
|
||||||
|
|
16
README.rst
16
README.rst
|
@ -5,16 +5,16 @@ libsass-python: Sass_/SCSS for Python
|
||||||
:alt: PyPI
|
:alt: PyPI
|
||||||
:target: https://pypi.org/pypi/libsass/
|
:target: https://pypi.org/pypi/libsass/
|
||||||
|
|
||||||
.. image:: https://dev.azure.com/asottile/asottile/_apis/build/status/sass.libsass-python?branchName=master
|
.. image:: https://dev.azure.com/asottile/asottile/_apis/build/status/sass.libsass-python?branchName=main
|
||||||
:target: https://dev.azure.com/asottile/asottile/_build/latest?definitionId=22&branchName=master
|
:target: https://dev.azure.com/asottile/asottile/_build/latest?definitionId=22&branchName=main
|
||||||
:alt: Build Status
|
:alt: Build Status
|
||||||
|
|
||||||
.. image:: https://img.shields.io/azure-devops/coverage/asottile/asottile/22/master.svg
|
.. image:: https://img.shields.io/azure-devops/coverage/asottile/asottile/22/main.svg
|
||||||
:target: https://dev.azure.com/asottile/asottile/_build/latest?definitionId=22&branchName=master
|
:target: https://dev.azure.com/asottile/asottile/_build/latest?definitionId=22&branchName=main
|
||||||
:alt: Coverage Status
|
:alt: Coverage Status
|
||||||
|
|
||||||
.. image:: https://results.pre-commit.ci/badge/github/sass/libsass-python/master.svg
|
.. image:: https://results.pre-commit.ci/badge/github/sass/libsass-python/main.svg
|
||||||
:target: https://results.pre-commit.ci/latest/github/sass/libsass-python/master
|
:target: https://results.pre-commit.ci/latest/github/sass/libsass-python/main
|
||||||
:alt: pre-commit.ci status
|
:alt: pre-commit.ci status
|
||||||
|
|
||||||
This package provides a simple Python extension module ``sass`` which is
|
This package provides a simple Python extension module ``sass`` which is
|
||||||
|
@ -22,9 +22,9 @@ binding LibSass_ (written in C/C++ by Hampton Catlin and Aaron Leung).
|
||||||
It's very straightforward and there isn't any headache related Python
|
It's very straightforward and there isn't any headache related Python
|
||||||
distribution/deployment. That means you can add just ``libsass`` into
|
distribution/deployment. That means you can add just ``libsass`` into
|
||||||
your ``setup.py``'s ``install_requires`` list or ``requirements.txt`` file.
|
your ``setup.py``'s ``install_requires`` list or ``requirements.txt`` file.
|
||||||
Need no Ruby nor Node.js.
|
No need for Ruby nor Node.js.
|
||||||
|
|
||||||
It currently supports CPython 2.7, 3.6--3.8, and PyPy 2.3+!
|
It currently supports CPython 3.6+, and PyPy 3!
|
||||||
|
|
||||||
.. _Sass: https://sass-lang.com/
|
.. _Sass: https://sass-lang.com/
|
||||||
.. _LibSass: https://github.com/sass/libsass
|
.. _LibSass: https://github.com/sass/libsass
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
trigger:
|
trigger:
|
||||||
branches:
|
branches:
|
||||||
include: [master, test-me-*]
|
include: [main, test-me-*]
|
||||||
tags:
|
tags:
|
||||||
include: ['*']
|
include: ['*']
|
||||||
|
|
||||||
|
@ -13,30 +13,21 @@ resources:
|
||||||
type: github
|
type: github
|
||||||
endpoint: github
|
endpoint: github
|
||||||
name: asottile/azure-pipeline-templates
|
name: asottile/azure-pipeline-templates
|
||||||
ref: refs/tags/v2.1.0
|
ref: refs/tags/v2.4.0
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
- template: job--python-tox.yml@asottile
|
- template: job--python-tox.yml@asottile
|
||||||
parameters:
|
parameters:
|
||||||
toxenvs: [py27, py36]
|
toxenvs: [py37]
|
||||||
os: macos
|
os: macos
|
||||||
wheel_tags: true
|
wheel_tags: true
|
||||||
- template: job--python-tox.yml@asottile
|
- template: job--python-tox.yml@asottile
|
||||||
parameters:
|
parameters:
|
||||||
toxenvs: [py27]
|
toxenvs: [py37]
|
||||||
os: windows
|
|
||||||
architectures: [x64, x86]
|
|
||||||
name_postfix: _py27
|
|
||||||
wheel_tags: true
|
|
||||||
pre_test:
|
|
||||||
- script: rm -rf libsass/test
|
|
||||||
- template: job--python-tox.yml@asottile
|
|
||||||
parameters:
|
|
||||||
toxenvs: [py36]
|
|
||||||
os: windows
|
os: windows
|
||||||
architectures: [x64, x86]
|
architectures: [x64, x86]
|
||||||
wheel_tags: true
|
wheel_tags: true
|
||||||
- template: job--python-tox.yml@asottile
|
- template: job--python-tox.yml@asottile
|
||||||
parameters:
|
parameters:
|
||||||
toxenvs: [pypy, pypy3, py27, py36, py37, py38, py39]
|
toxenvs: [pypy3, py36, py37, py38, py39]
|
||||||
os: linux
|
os: linux
|
||||||
|
|
|
@ -23,13 +23,13 @@ def main():
|
||||||
os.makedirs('dist', exist_ok=True)
|
os.makedirs('dist', exist_ok=True)
|
||||||
for python in ('cp27-cp27mu', 'cp36-cp36m'):
|
for python in ('cp27-cp27mu', 'cp36-cp36m'):
|
||||||
with tempfile.TemporaryDirectory() as work:
|
with tempfile.TemporaryDirectory() as work:
|
||||||
pip = '/opt/python/{}/bin/pip'.format(python)
|
pip = f'/opt/python/{python}/bin/pip'
|
||||||
check_call(
|
check_call(
|
||||||
'docker', 'run', '-ti',
|
'docker', 'run', '-ti',
|
||||||
# Use this so the files are not owned by root
|
# Use this so the files are not owned by root
|
||||||
'--user', '{}:{}'.format(os.getuid(), os.getgid()),
|
'--user', f'{os.getuid()}:{os.getgid()}',
|
||||||
# We'll do building in /work and copy results to /dist
|
# We'll do building in /work and copy results to /dist
|
||||||
'-v', '{}:/work:rw'.format(work),
|
'-v', f'{work}:/work:rw',
|
||||||
'-v', '{}:/dist:rw'.format(os.path.abspath('dist')),
|
'-v', '{}:/dist:rw'.format(os.path.abspath('dist')),
|
||||||
'quay.io/pypa/manylinux1_x86_64:latest',
|
'quay.io/pypa/manylinux1_x86_64:latest',
|
||||||
'bash', '-exc',
|
'bash', '-exc',
|
||||||
|
@ -40,4 +40,4 @@ def main():
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
exit(main())
|
raise SystemExit(main())
|
||||||
|
|
|
@ -56,4 +56,4 @@ def main() -> int:
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
exit(main())
|
raise SystemExit(main())
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
libsass-python (0.21.0-ok2) yangtze; urgency=medium
|
|
||||||
|
|
||||||
* Fix command 'install' has no such option 'install_layout'.
|
|
||||||
Add pysassc-man.patch.
|
|
||||||
|
|
||||||
-- sufang <sufang@kylinos.cn> Tue, 11 Oct 2022 11:07:40 +0800
|
|
||||||
|
|
||||||
libsass-python (0.21.0-ok1) yangtze; urgency=medium
|
|
||||||
|
|
||||||
* Build for openkylin.
|
|
||||||
|
|
||||||
-- sufang <sufang@kylinos.cn> Tue, 11 Oct 2022 10:19:07 +0800
|
|
|
@ -1,47 +0,0 @@
|
||||||
Source: libsass-python
|
|
||||||
Section: python
|
|
||||||
Priority: optional
|
|
||||||
Maintainer: OpenKylin Developers <packaging@lists.openkylin.top>
|
|
||||||
Build-Depends:
|
|
||||||
debhelper-compat (= 13),
|
|
||||||
dh-python,
|
|
||||||
python3-all-dev,
|
|
||||||
python3-setuptools,
|
|
||||||
python3-six,
|
|
||||||
python3-sphinx,
|
|
||||||
python3-werkzeug,
|
|
||||||
python3-flake8,
|
|
||||||
python3-pytest,
|
|
||||||
python3-doc,
|
|
||||||
python-flask-doc,
|
|
||||||
python-setuptools-doc,
|
|
||||||
libsass-dev (>= 3.6.5)
|
|
||||||
Standards-Version: 4.6.0
|
|
||||||
Vcs-Browser: https://gitee.com/openkylin/libsass-python
|
|
||||||
Vcs-Git: https://gitee.com/openkylin/libsass-python.git
|
|
||||||
Homepage: https://sass.github.io/libsass-python
|
|
||||||
Rules-Requires-Root: no
|
|
||||||
X-Python-Version: >= 2.6
|
|
||||||
X-Python3-Version: >= 3.2
|
|
||||||
|
|
||||||
Package: python3-libsass
|
|
||||||
Architecture: any
|
|
||||||
Depends: ${misc:Depends}, ${python3:Depends}, ${shlibs:Depends}
|
|
||||||
Description: SASS for Python 3: a straightforward binding of libsass for Python
|
|
||||||
This package provides a simple Python 3 extension module sass which is binding
|
|
||||||
Libsass (written in C/C++ by Hampton Catlin and Aaron Leung). It's very
|
|
||||||
straightforward and there isn't any headache related Python
|
|
||||||
distribution/deployment.
|
|
||||||
That means you can add just libsass into your setup.py's install_requires list
|
|
||||||
or requirements.txt file. Need no Ruby nor Node.js.
|
|
||||||
|
|
||||||
Package: pysassc
|
|
||||||
Section: web
|
|
||||||
Architecture: all
|
|
||||||
Depends: ${misc:Depends}, ${python3:Depends}, ${shlibs:Depends}, python3-libsass
|
|
||||||
Description: SASS for Python: command line utility for libsass
|
|
||||||
This package provides a simple Python script to access libsass
|
|
||||||
functionnalities.
|
|
||||||
Libsass (written in C/C++ by Hampton Catlin and Aaron Leung). It's very
|
|
||||||
straightforward and there isn't any headache related Python
|
|
||||||
distribution/deployment.
|
|
|
@ -1,86 +0,0 @@
|
||||||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
|
||||||
Upstream-Name: libsass-python
|
|
||||||
Source: <url://example.com>
|
|
||||||
#
|
|
||||||
# Please double check copyright with the licensecheck(1) command.
|
|
||||||
|
|
||||||
Files: .ackrc
|
|
||||||
.coveragerc
|
|
||||||
.gitignore
|
|
||||||
.gitmodules
|
|
||||||
.pre-commit-config.yaml
|
|
||||||
CODE_OF_CONDUCT.md
|
|
||||||
CONTRIBUTING.rst
|
|
||||||
MANIFEST.in
|
|
||||||
README.rst
|
|
||||||
_sass.c
|
|
||||||
azure-pipelines.yml
|
|
||||||
bin/build-manylinux-wheels
|
|
||||||
bin/download-windows-wheels
|
|
||||||
docs/Makefile
|
|
||||||
docs/changes.rst
|
|
||||||
docs/conf.py
|
|
||||||
docs/frameworks/flask.rst
|
|
||||||
docs/index.rst
|
|
||||||
docs/make.bat
|
|
||||||
docs/pysassc.rst
|
|
||||||
docs/sass.rst
|
|
||||||
docs/sassutils.rst
|
|
||||||
docs/sassutils/builder.rst
|
|
||||||
docs/sassutils/distutils.rst
|
|
||||||
docs/sassutils/wsgi.rst
|
|
||||||
pysassc.py
|
|
||||||
requirements-dev.txt
|
|
||||||
sass.py
|
|
||||||
sassc.py
|
|
||||||
sasstests.py
|
|
||||||
sassutils/__init__.py
|
|
||||||
sassutils/_compat.py
|
|
||||||
sassutils/builder.py
|
|
||||||
sassutils/distutils.py
|
|
||||||
sassutils/wsgi.py
|
|
||||||
setup.cfg
|
|
||||||
setup.py
|
|
||||||
test/_f.scss
|
|
||||||
test/a.scss
|
|
||||||
test/b.scss
|
|
||||||
test/c.scss
|
|
||||||
test/d.scss
|
|
||||||
test/e.scss
|
|
||||||
test/g.scss
|
|
||||||
test/h.sass
|
|
||||||
test/subdir/_sub.scss
|
|
||||||
test/subdir/recur.scss
|
|
||||||
testpkg/setup.py
|
|
||||||
testpkg/testpkg/__init__.py
|
|
||||||
testpkg/testpkg/static/css/README
|
|
||||||
testpkg/testpkg/static/scss/a.scss
|
|
||||||
tox.ini
|
|
||||||
Copyright: __NO_COPYRIGHT_NOR_LICENSE__
|
|
||||||
License: __NO_COPYRIGHT_NOR_LICENSE__
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------------
|
|
||||||
# Files marked as NO_LICENSE_TEXT_FOUND may be covered by the following
|
|
||||||
# license/copyright files.
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------------
|
|
||||||
# License file: LICENSE
|
|
||||||
Copyright (c) 2015 Hong Minhee <https://hongminhee.org/>
|
|
||||||
.
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
.
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
.
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
|
@ -1 +0,0 @@
|
||||||
../docs/changes.rst
|
|
|
@ -1,2 +0,0 @@
|
||||||
usr/bin/sassc
|
|
||||||
usr/lib/*/dist-packages/__pycache__/*.pyc
|
|
|
@ -1 +0,0 @@
|
||||||
# You must remove unused comment lines for the released package.
|
|
|
@ -1 +0,0 @@
|
||||||
usr/bin/pysassc
|
|
|
@ -1 +0,0 @@
|
||||||
debian/tmp/usr/share/man/man1/pysassc.1
|
|
|
@ -1,4 +0,0 @@
|
||||||
usr/lib/python3*/*-packages/*.py
|
|
||||||
usr/lib/python3*/*-packages/_sass*.so
|
|
||||||
usr/lib/python3*/*-packages/*.egg-info/
|
|
||||||
usr/lib/python3*/*-packages/sassutils/
|
|
|
@ -1 +0,0 @@
|
||||||
usr/share/man/man3/libsass.3
|
|
|
@ -1,41 +0,0 @@
|
||||||
#!/usr/bin/make -f
|
|
||||||
export DH_VERBOSE=1
|
|
||||||
export PYTHON_EGG_CACHE=$(CURDIR)/debian/tmp
|
|
||||||
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
|
|
||||||
|
|
||||||
export SYSTEM_SASS = 1
|
|
||||||
|
|
||||||
export SETUPTOOLS_USE_DISTUTILS=stdlib
|
|
||||||
|
|
||||||
%: .libsass-upstream-version
|
|
||||||
dh $@ --with python3 --buildsystem=pybuild
|
|
||||||
|
|
||||||
.libsass-upstream-version:
|
|
||||||
dpkg-query -f '$${Version}\n' -W libsass-dev|sed 's/-.*//' > .libsass-upstream-version
|
|
||||||
|
|
||||||
override_dh_auto_build:
|
|
||||||
pybuild --build -p "$(shell py3versions -vr)"
|
|
||||||
# build doc once
|
|
||||||
pybuild -s custom --build -p $(shell py3versions -vd) \
|
|
||||||
--build-args="env PYTHONPATH={build_dir} python3 -m sphinx -N -bman docs/ build/man"
|
|
||||||
|
|
||||||
override_dh_auto_install:
|
|
||||||
dh_auto_install -O--buildsystem=pybuild
|
|
||||||
mkdir -p $(CURDIR)/debian/tmp/usr/share/man/man1
|
|
||||||
mkdir -p $(CURDIR)/debian/tmp/usr/share/man/man3
|
|
||||||
cp $(CURDIR)/build/man/pysassc.1 $(CURDIR)/debian/tmp/usr/share/man/man1/
|
|
||||||
cp $(CURDIR)/build/man/libsass.3 $(CURDIR)/debian/tmp/usr/share/man/man3/
|
|
||||||
rm $(CURDIR)/debian/tmp/usr/lib/python*/dist-packages/sasstests.py
|
|
||||||
sed -i '1c#!/usr/bin/python3' $(CURDIR)/debian/tmp/usr/bin/pysassc
|
|
||||||
|
|
||||||
override_dh_auto_test:
|
|
||||||
ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
|
|
||||||
# Skip DistutilsTestCase.* to not rebuild sass again
|
|
||||||
pybuild -s custom --test -p "$(shell py3versions -vr)" \
|
|
||||||
--test-args="cd {build_dir}; \
|
|
||||||
{interpreter} -m pytest -k 'not DistutilsTestCase' sasstests.py"
|
|
||||||
endif
|
|
||||||
|
|
||||||
override_dh_auto_clean:
|
|
||||||
dh_auto_clean -O--buildsystem=pybuild
|
|
||||||
rm -fr libsass.egg-info .libsass-upstream-version
|
|
|
@ -1 +0,0 @@
|
||||||
3.0 (native)
|
|
|
@ -1,5 +0,0 @@
|
||||||
---
|
|
||||||
Bug-Database: https://github.com/dahlia/libsass-python/issues
|
|
||||||
Bug-Submit: https://github.com/dahlia/libsass-python/issues/new
|
|
||||||
Repository: https://github.com/dahlia/libsass-python.git
|
|
||||||
Repository-Browse: https://github.com/dahlia/libsass-python
|
|
|
@ -1,4 +0,0 @@
|
||||||
version=4
|
|
||||||
opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%@PACKAGE@-$1.tar.gz%" \
|
|
||||||
https://github.com/dahlia/libsass-python/tags \
|
|
||||||
(?:.*?/)?v?(\d[\d.]*)\.tar\.gz debian uupdate
|
|
|
@ -1,7 +1,15 @@
|
||||||
Changelog
|
Changelog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
Version 0.21.1
|
Version 0.22.0
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Released on November 12, 2022.
|
||||||
|
|
||||||
|
- Remove python 2.x support [:issue:`373` by anthony sottile].
|
||||||
|
- Remove deprecated ``sassc`` cli [:issue:`379` by anthony sottile].
|
||||||
|
|
||||||
|
Version 0.21.0
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
Released on May 20, 2021.
|
Released on May 20, 2021.
|
||||||
|
|
46
docs/conf.py
46
docs/conf.py
|
@ -1,4 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
#
|
#
|
||||||
# libsass documentation build configuration file, created by
|
# libsass documentation build configuration file, created by
|
||||||
# sphinx-quickstart on Sun Aug 19 22:45:57 2012.
|
# sphinx-quickstart on Sun Aug 19 22:45:57 2012.
|
||||||
|
@ -14,12 +13,13 @@ import os
|
||||||
import sys
|
import sys
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
|
import sass
|
||||||
|
|
||||||
# If extensions (or modules to document with autodoc) are in another directory,
|
# If extensions (or modules to document with autodoc) are in another directory,
|
||||||
# add these directories to sys.path here. If the directory is relative to the
|
# add these directories to sys.path here. If the directory is relative to the
|
||||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||||
sys.path.insert(0, os.path.abspath('..'))
|
sys.path.insert(0, os.path.abspath('..'))
|
||||||
|
|
||||||
import sass
|
|
||||||
|
|
||||||
# -- General configuration -----------------------------------------------------
|
# -- General configuration -----------------------------------------------------
|
||||||
|
|
||||||
|
@ -48,8 +48,8 @@ source_suffix = '.rst'
|
||||||
master_doc = 'index'
|
master_doc = 'index'
|
||||||
|
|
||||||
# General information about the project.
|
# General information about the project.
|
||||||
project = u'libsass'
|
project = 'libsass'
|
||||||
copyright = u'2012, Hong Minhee'
|
copyright = '2012, Hong Minhee'
|
||||||
|
|
||||||
# The version info for the project you're documenting, acts as replacement for
|
# The version info for the project you're documenting, acts as replacement for
|
||||||
# |version| and |release|, also used in various other places throughout the
|
# |version| and |release|, also used in various other places throughout the
|
||||||
|
@ -180,23 +180,23 @@ htmlhelp_basename = 'libsassdoc'
|
||||||
# -- Options for LaTeX output --------------------------------------------------
|
# -- Options for LaTeX output --------------------------------------------------
|
||||||
|
|
||||||
latex_elements = {
|
latex_elements = {
|
||||||
# The paper size ('letterpaper' or 'a4paper').
|
# The paper size ('letterpaper' or 'a4paper').
|
||||||
#'papersize': 'letterpaper',
|
# 'papersize': 'letterpaper',
|
||||||
|
|
||||||
# The font size ('10pt', '11pt' or '12pt').
|
# The font size ('10pt', '11pt' or '12pt').
|
||||||
#'pointsize': '10pt',
|
# 'pointsize': '10pt',
|
||||||
|
|
||||||
# Additional stuff for the LaTeX preamble.
|
# Additional stuff for the LaTeX preamble.
|
||||||
#'preamble': '',
|
# 'preamble': '',
|
||||||
}
|
}
|
||||||
|
|
||||||
# Grouping the document tree into LaTeX files. List of tuples
|
# Grouping the document tree into LaTeX files. List of tuples
|
||||||
# (source start file, target name, title, author, documentclass [howto/manual]).
|
# (source start file, target name, title, author, documentclass [howto/manual]).
|
||||||
latex_documents = [
|
latex_documents = [
|
||||||
(
|
(
|
||||||
'index', 'libsass.tex', u'libsass Documentation',
|
'index', 'libsass.tex', 'libsass Documentation',
|
||||||
u'Hong Minhee', 'manual',
|
'Hong Minhee', 'manual',
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
# The name of an image file (relative to this directory) to place at the top of
|
# The name of an image file (relative to this directory) to place at the top of
|
||||||
|
@ -226,10 +226,8 @@ latex_documents = [
|
||||||
# (source start file, name, description, authors, manual section).
|
# (source start file, name, description, authors, manual section).
|
||||||
man_pages = [
|
man_pages = [
|
||||||
(
|
(
|
||||||
'index', 'libsass', u'libsass Documentation', [u'Hong Minhee'], 3,
|
'index', 'libsass', 'libsass Documentation',
|
||||||
),
|
['Hong Minhee'], 1,
|
||||||
(
|
|
||||||
'pysassc', 'pysassc', u'pysassc Documentation', [u'Hong Minhee'], 1,
|
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -243,11 +241,11 @@ man_pages = [
|
||||||
# (source start file, target name, title, author,
|
# (source start file, target name, title, author,
|
||||||
# dir menu entry, description, category)
|
# dir menu entry, description, category)
|
||||||
texinfo_documents = [
|
texinfo_documents = [
|
||||||
(
|
(
|
||||||
'index', 'libsass', u'libsass Documentation',
|
'index', 'libsass', 'libsass Documentation',
|
||||||
u'Hong Minhee', 'libsass', 'One line description of project.',
|
'Hong Minhee', 'libsass', 'One line description of project.',
|
||||||
'Miscellaneous',
|
'Miscellaneous',
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
# Documents to append as an appendix to all manuals.
|
# Documents to append as an appendix to all manuals.
|
||||||
|
@ -271,7 +269,7 @@ intersphinx_mapping = {
|
||||||
extlinks = {
|
extlinks = {
|
||||||
'issue': ('https://github.com/sass/libsass-python/issues/%s', '#'),
|
'issue': ('https://github.com/sass/libsass-python/issues/%s', '#'),
|
||||||
'branch': (
|
'branch': (
|
||||||
'https://github.com/sass/libsass-python/compare/master...%s',
|
'https://github.com/sass/libsass-python/compare/main...%s',
|
||||||
'',
|
'',
|
||||||
),
|
),
|
||||||
'commit': ('https://github.com/sass/libsass-python/commit/%s', ''),
|
'commit': ('https://github.com/sass/libsass-python/commit/%s', ''),
|
||||||
|
|
|
@ -8,7 +8,7 @@ distribution/deployment. That means you can add just ``libsass`` into
|
||||||
your :file:`setup.py`'s ``install_requires`` list or :file:`requirements.txt`
|
your :file:`setup.py`'s ``install_requires`` list or :file:`requirements.txt`
|
||||||
file.
|
file.
|
||||||
|
|
||||||
It currently supports CPython 2.6, 2.7, 3.5--3.7, and PyPy 2.3+!
|
It currently supports CPython 3.6+ and PyPy 3!
|
||||||
|
|
||||||
.. _Sass: https://sass-lang.com/
|
.. _Sass: https://sass-lang.com/
|
||||||
.. _LibSass: https://github.com/sass/libsass
|
.. _LibSass: https://github.com/sass/libsass
|
||||||
|
@ -133,17 +133,17 @@ GitHub (Git repository + issues)
|
||||||
https://github.com/sass/libsass-python
|
https://github.com/sass/libsass-python
|
||||||
|
|
||||||
Azure Pipelines CI (linux + windows)
|
Azure Pipelines CI (linux + windows)
|
||||||
https://dev.azure.com/asottile/asottile/_build/latest?definitionId=22&branchName=master
|
https://dev.azure.com/asottile/asottile/_build/latest?definitionId=22&branchName=main
|
||||||
|
|
||||||
.. image:: https://dev.azure.com/asottile/asottile/_apis/build/status/sass.libsass-python?branchName=master
|
.. image:: https://dev.azure.com/asottile/asottile/_apis/build/status/sass.libsass-python?branchName=main
|
||||||
:target: https://dev.azure.com/asottile/asottile/_build/latest?definitionId=22&branchName=master
|
:target: https://dev.azure.com/asottile/asottile/_build/latest?definitionId=22&branchName=main
|
||||||
:alt: Build Status
|
:alt: Build Status
|
||||||
|
|
||||||
Azure Pipelines Coverage (Test coverage)
|
Azure Pipelines Coverage (Test coverage)
|
||||||
https://dev.azure.com/asottile/asottile/_build/latest?definitionId=22&branchName=master
|
https://dev.azure.com/asottile/asottile/_build/latest?definitionId=22&branchName=main
|
||||||
|
|
||||||
.. image:: https://img.shields.io/azure-devops/coverage/asottile/asottile/22/master.svg
|
.. image:: https://img.shields.io/azure-devops/coverage/asottile/asottile/22/main.svg
|
||||||
:target: https://dev.azure.com/asottile/asottile/_build/latest?definitionId=22&branchName=master
|
:target: https://dev.azure.com/asottile/asottile/_build/latest?definitionId=22&branchName=main
|
||||||
:alt: Coverage Status
|
:alt: Coverage Status
|
||||||
|
|
||||||
PyPI
|
PyPI
|
||||||
|
|
|
@ -88,10 +88,7 @@ There are options as well:
|
||||||
.. _SassC: https://github.com/sass/sassc
|
.. _SassC: https://github.com/sass/sassc
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
import functools
|
import functools
|
||||||
import io
|
|
||||||
import optparse
|
import optparse
|
||||||
import sys
|
import sys
|
||||||
import warnings
|
import warnings
|
||||||
|
@ -219,7 +216,7 @@ def main(argv=sys.argv, stdout=sys.stdout, stderr=sys.stderr):
|
||||||
include_paths=options.include_paths,
|
include_paths=options.include_paths,
|
||||||
precision=options.precision,
|
precision=options.precision,
|
||||||
)
|
)
|
||||||
except (IOError, OSError) as e:
|
except OSError as e:
|
||||||
error(e)
|
error(e)
|
||||||
return 3
|
return 3
|
||||||
except sass.CompileError as e:
|
except sass.CompileError as e:
|
||||||
|
@ -229,10 +226,10 @@ def main(argv=sys.argv, stdout=sys.stdout, stderr=sys.stderr):
|
||||||
if len(args) < 2:
|
if len(args) < 2:
|
||||||
print(css, file=stdout)
|
print(css, file=stdout)
|
||||||
else:
|
else:
|
||||||
with io.open(args[1], 'w', encoding='utf-8', newline='') as f:
|
with open(args[1], 'w', encoding='utf-8', newline='') as f:
|
||||||
f.write(css)
|
f.write(css)
|
||||||
if source_map_filename:
|
if source_map_filename:
|
||||||
with io.open(
|
with open(
|
||||||
source_map_filename, 'w', encoding='utf-8', newline='',
|
source_map_filename, 'w', encoding='utf-8', newline='',
|
||||||
) as f:
|
) as f:
|
||||||
f.write(source_map)
|
f.write(source_map)
|
||||||
|
|
95
sass.py
95
sass.py
|
@ -10,28 +10,21 @@ type.
|
||||||
'a b {\n color: blue; }\n'
|
'a b {\n color: blue; }\n'
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from __future__ import absolute_import
|
import collections.abc
|
||||||
|
|
||||||
import collections
|
|
||||||
import inspect
|
import inspect
|
||||||
import io
|
|
||||||
import os
|
|
||||||
import os.path
|
import os.path
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
from six import string_types, text_type, PY2
|
|
||||||
|
|
||||||
import _sass
|
import _sass
|
||||||
from sassutils._compat import collections_abc
|
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'MODES', 'OUTPUT_STYLES', 'SOURCE_COMMENTS', 'CompileError', 'SassColor',
|
'MODES', 'OUTPUT_STYLES', 'SOURCE_COMMENTS', 'CompileError', 'SassColor',
|
||||||
'SassError', 'SassFunction', 'SassList', 'SassMap', 'SassNumber',
|
'SassError', 'SassFunction', 'SassList', 'SassMap', 'SassNumber',
|
||||||
'SassWarning', 'and_join', 'compile', 'libsass_version',
|
'SassWarning', 'and_join', 'compile', 'libsass_version',
|
||||||
)
|
)
|
||||||
__version__ = '0.21.0'
|
__version__ = '0.22.0'
|
||||||
libsass_version = _sass.libsass_version
|
libsass_version = _sass.libsass_version
|
||||||
|
|
||||||
|
|
||||||
|
@ -52,19 +45,19 @@ MODES = frozenset(('string', 'filename', 'dirname'))
|
||||||
|
|
||||||
|
|
||||||
def to_native_s(s):
|
def to_native_s(s):
|
||||||
if isinstance(s, bytes) and not PY2: # pragma: no cover (py3)
|
if isinstance(s, bytes):
|
||||||
s = s.decode('UTF-8')
|
return s.decode('UTF-8')
|
||||||
elif isinstance(s, text_type) and PY2: # pragma: no cover (py2)
|
else:
|
||||||
s = s.encode('UTF-8')
|
return s
|
||||||
return s
|
|
||||||
|
|
||||||
|
|
||||||
class CompileError(ValueError):
|
class CompileError(ValueError):
|
||||||
"""The exception type that is raised by :func:`compile()`.
|
"""The exception type that is raised by :func:`compile()`.
|
||||||
It is a subtype of :exc:`exceptions.ValueError`.
|
It is a subtype of :exc:`exceptions.ValueError`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, msg):
|
def __init__(self, msg):
|
||||||
super(CompileError, self).__init__(to_native_s(msg))
|
super().__init__(to_native_s(msg))
|
||||||
|
|
||||||
|
|
||||||
def mkdirp(path):
|
def mkdirp(path):
|
||||||
|
@ -76,7 +69,7 @@ def mkdirp(path):
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
class SassFunction(object):
|
class SassFunction:
|
||||||
"""Custom function for Sass. It can be instantiated using
|
"""Custom function for Sass. It can be instantiated using
|
||||||
:meth:`from_lambda()` and :meth:`from_named_function()` as well.
|
:meth:`from_lambda()` and :meth:`from_named_function()` as well.
|
||||||
|
|
||||||
|
@ -107,16 +100,10 @@ class SassFunction(object):
|
||||||
:rtype: :class:`SassFunction`
|
:rtype: :class:`SassFunction`
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if PY2: # pragma: no cover
|
a = inspect.getfullargspec(lambda_)
|
||||||
a = inspect.getargspec(lambda_)
|
varargs, varkw, defaults, kwonlyargs = (
|
||||||
varargs, varkw, defaults, kwonlyargs = (
|
a.varargs, a.varkw, a.defaults, a.kwonlyargs,
|
||||||
a.varargs, a.keywords, a.defaults, None,
|
)
|
||||||
)
|
|
||||||
else: # pragma: no cover
|
|
||||||
a = inspect.getfullargspec(lambda_)
|
|
||||||
varargs, varkw, defaults, kwonlyargs = (
|
|
||||||
a.varargs, a.varkw, a.defaults, a.kwonlyargs,
|
|
||||||
)
|
|
||||||
|
|
||||||
if varargs or varkw or defaults or kwonlyargs:
|
if varargs or varkw or defaults or kwonlyargs:
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
|
@ -142,9 +129,9 @@ class SassFunction(object):
|
||||||
return cls.from_lambda(function.__name__, function)
|
return cls.from_lambda(function.__name__, function)
|
||||||
|
|
||||||
def __init__(self, name, arguments, callable_):
|
def __init__(self, name, arguments, callable_):
|
||||||
if not isinstance(name, string_types):
|
if not isinstance(name, str):
|
||||||
raise TypeError('name must be a string, not ' + repr(name))
|
raise TypeError('name must be a string, not ' + repr(name))
|
||||||
elif not isinstance(arguments, collections_abc.Sequence):
|
elif not isinstance(arguments, collections.abc.Sequence):
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
'arguments must be a sequence, not ' +
|
'arguments must be a sequence, not ' +
|
||||||
repr(arguments),
|
repr(arguments),
|
||||||
|
@ -263,7 +250,7 @@ def compile_dirname(
|
||||||
if s:
|
if s:
|
||||||
v = v.decode('UTF-8')
|
v = v.decode('UTF-8')
|
||||||
mkdirp(os.path.dirname(output_filename))
|
mkdirp(os.path.dirname(output_filename))
|
||||||
with io.open(
|
with open(
|
||||||
output_filename, 'w', encoding='UTF-8', newline='',
|
output_filename, 'w', encoding='UTF-8', newline='',
|
||||||
) as output_file:
|
) as output_file:
|
||||||
output_file.write(v)
|
output_file.write(v)
|
||||||
|
@ -277,7 +264,7 @@ def _check_no_remaining_kwargs(func, kwargs):
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
'{}() got unexpected keyword argument(s) {}'.format(
|
'{}() got unexpected keyword argument(s) {}'.format(
|
||||||
func.__name__,
|
func.__name__,
|
||||||
', '.join("'{}'".format(arg) for arg in sorted(kwargs)),
|
', '.join(f"'{arg}'" for arg in sorted(kwargs)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -563,7 +550,7 @@ def compile(**kwargs):
|
||||||
)
|
)
|
||||||
precision = kwargs.pop('precision', 5)
|
precision = kwargs.pop('precision', 5)
|
||||||
output_style = kwargs.pop('output_style', 'nested')
|
output_style = kwargs.pop('output_style', 'nested')
|
||||||
if not isinstance(output_style, string_types):
|
if not isinstance(output_style, str):
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
'output_style must be a string, not ' +
|
'output_style must be a string, not ' +
|
||||||
repr(output_style),
|
repr(output_style),
|
||||||
|
@ -586,7 +573,7 @@ def compile(**kwargs):
|
||||||
elif source_comments in ('line_numbers', 'default'):
|
elif source_comments in ('line_numbers', 'default'):
|
||||||
deprecation_message = (
|
deprecation_message = (
|
||||||
'you can simply pass True to '
|
'you can simply pass True to '
|
||||||
"source_comments instead of " +
|
'source_comments instead of ' +
|
||||||
repr(source_comments)
|
repr(source_comments)
|
||||||
)
|
)
|
||||||
source_comments = True
|
source_comments = True
|
||||||
|
@ -612,9 +599,9 @@ def compile(**kwargs):
|
||||||
|
|
||||||
def _get_file_arg(key):
|
def _get_file_arg(key):
|
||||||
ret = kwargs.pop(key, None)
|
ret = kwargs.pop(key, None)
|
||||||
if ret is not None and not isinstance(ret, string_types):
|
if ret is not None and not isinstance(ret, str):
|
||||||
raise TypeError('{} must be a string, not {!r}'.format(key, ret))
|
raise TypeError(f'{key} must be a string, not {ret!r}')
|
||||||
elif isinstance(ret, text_type):
|
elif isinstance(ret, str):
|
||||||
ret = ret.encode(fs_encoding)
|
ret = ret.encode(fs_encoding)
|
||||||
if ret and 'filename' not in modes:
|
if ret and 'filename' not in modes:
|
||||||
raise CompileError(
|
raise CompileError(
|
||||||
|
@ -631,25 +618,25 @@ def compile(**kwargs):
|
||||||
omit_source_map_url = kwargs.pop('omit_source_map_url', False)
|
omit_source_map_url = kwargs.pop('omit_source_map_url', False)
|
||||||
source_map_root = kwargs.pop('source_map_root', None)
|
source_map_root = kwargs.pop('source_map_root', None)
|
||||||
|
|
||||||
if isinstance(source_map_root, text_type):
|
if isinstance(source_map_root, str):
|
||||||
source_map_root = source_map_root.encode('utf-8')
|
source_map_root = source_map_root.encode('utf-8')
|
||||||
|
|
||||||
# #208: cwd is always included in include paths
|
# #208: cwd is always included in include paths
|
||||||
include_paths = (os.getcwd(),)
|
include_paths = (os.getcwd(),)
|
||||||
include_paths += tuple(kwargs.pop('include_paths', ()) or ())
|
include_paths += tuple(kwargs.pop('include_paths', ()) or ())
|
||||||
include_paths = os.pathsep.join(include_paths)
|
include_paths = os.pathsep.join(include_paths)
|
||||||
if isinstance(include_paths, text_type):
|
if isinstance(include_paths, str):
|
||||||
include_paths = include_paths.encode(fs_encoding)
|
include_paths = include_paths.encode(fs_encoding)
|
||||||
|
|
||||||
custom_functions = kwargs.pop('custom_functions', ())
|
custom_functions = kwargs.pop('custom_functions', ())
|
||||||
if isinstance(custom_functions, collections_abc.Mapping):
|
if isinstance(custom_functions, collections.abc.Mapping):
|
||||||
custom_functions = [
|
custom_functions = [
|
||||||
SassFunction.from_lambda(name, lambda_)
|
SassFunction.from_lambda(name, lambda_)
|
||||||
for name, lambda_ in custom_functions.items()
|
for name, lambda_ in custom_functions.items()
|
||||||
]
|
]
|
||||||
elif isinstance(
|
elif isinstance(
|
||||||
custom_functions,
|
custom_functions,
|
||||||
(collections_abc.Set, collections_abc.Sequence),
|
(collections.abc.Set, collections.abc.Sequence),
|
||||||
):
|
):
|
||||||
custom_functions = [
|
custom_functions = [
|
||||||
func if isinstance(func, SassFunction)
|
func if isinstance(func, SassFunction)
|
||||||
|
@ -676,7 +663,7 @@ def compile(**kwargs):
|
||||||
|
|
||||||
if 'string' in modes:
|
if 'string' in modes:
|
||||||
string = kwargs.pop('string')
|
string = kwargs.pop('string')
|
||||||
if isinstance(string, text_type):
|
if isinstance(string, str):
|
||||||
string = string.encode('utf-8')
|
string = string.encode('utf-8')
|
||||||
indented = kwargs.pop('indented', False)
|
indented = kwargs.pop('indented', False)
|
||||||
if not isinstance(indented, bool):
|
if not isinstance(indented, bool):
|
||||||
|
@ -695,11 +682,11 @@ def compile(**kwargs):
|
||||||
return v.decode('utf-8')
|
return v.decode('utf-8')
|
||||||
elif 'filename' in modes:
|
elif 'filename' in modes:
|
||||||
filename = kwargs.pop('filename')
|
filename = kwargs.pop('filename')
|
||||||
if not isinstance(filename, string_types):
|
if not isinstance(filename, str):
|
||||||
raise TypeError('filename must be a string, not ' + repr(filename))
|
raise TypeError('filename must be a string, not ' + repr(filename))
|
||||||
elif not os.path.isfile(filename):
|
elif not os.path.isfile(filename):
|
||||||
raise IOError('{!r} seems not a file'.format(filename))
|
raise OSError(f'{filename!r} seems not a file')
|
||||||
elif isinstance(filename, text_type):
|
elif isinstance(filename, str):
|
||||||
filename = filename.encode(fs_encoding)
|
filename = filename.encode(fs_encoding)
|
||||||
_check_no_remaining_kwargs(compile, kwargs)
|
_check_no_remaining_kwargs(compile, kwargs)
|
||||||
s, v, source_map = _sass.compile_filename(
|
s, v, source_map = _sass.compile_filename(
|
||||||
|
@ -780,9 +767,9 @@ class SassNumber(collections.namedtuple('SassNumber', ('value', 'unit'))):
|
||||||
|
|
||||||
def __new__(cls, value, unit):
|
def __new__(cls, value, unit):
|
||||||
value = float(value)
|
value = float(value)
|
||||||
if not isinstance(unit, text_type):
|
if not isinstance(unit, str):
|
||||||
unit = unit.decode('UTF-8')
|
unit = unit.decode('UTF-8')
|
||||||
return super(SassNumber, cls).__new__(cls, value, unit)
|
return super().__new__(cls, value, unit)
|
||||||
|
|
||||||
|
|
||||||
class SassColor(collections.namedtuple('SassColor', ('r', 'g', 'b', 'a'))):
|
class SassColor(collections.namedtuple('SassColor', ('r', 'g', 'b', 'a'))):
|
||||||
|
@ -792,7 +779,7 @@ class SassColor(collections.namedtuple('SassColor', ('r', 'g', 'b', 'a'))):
|
||||||
g = float(g)
|
g = float(g)
|
||||||
b = float(b)
|
b = float(b)
|
||||||
a = float(a)
|
a = float(a)
|
||||||
return super(SassColor, cls).__new__(cls, r, g, b, a)
|
return super().__new__(cls, r, g, b, a)
|
||||||
|
|
||||||
|
|
||||||
SASS_SEPARATOR_COMMA = collections.namedtuple('SASS_SEPARATOR_COMMA', ())()
|
SASS_SEPARATOR_COMMA = collections.namedtuple('SASS_SEPARATOR_COMMA', ())()
|
||||||
|
@ -802,7 +789,7 @@ SEPARATORS = frozenset((SASS_SEPARATOR_COMMA, SASS_SEPARATOR_SPACE))
|
||||||
|
|
||||||
class SassList(
|
class SassList(
|
||||||
collections.namedtuple(
|
collections.namedtuple(
|
||||||
'SassList', ('items', 'separator', 'bracketed'),
|
'SassList', ('items', 'separator', 'bracketed'),
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
|
|
||||||
|
@ -810,26 +797,26 @@ class SassList(
|
||||||
items = tuple(items)
|
items = tuple(items)
|
||||||
assert separator in SEPARATORS, separator
|
assert separator in SEPARATORS, separator
|
||||||
assert isinstance(bracketed, bool), bracketed
|
assert isinstance(bracketed, bool), bracketed
|
||||||
return super(SassList, cls).__new__(cls, items, separator, bracketed)
|
return super().__new__(cls, items, separator, bracketed)
|
||||||
|
|
||||||
|
|
||||||
class SassError(collections.namedtuple('SassError', ('msg',))):
|
class SassError(collections.namedtuple('SassError', ('msg',))):
|
||||||
|
|
||||||
def __new__(cls, msg):
|
def __new__(cls, msg):
|
||||||
if not isinstance(msg, text_type):
|
if not isinstance(msg, str):
|
||||||
msg = msg.decode('UTF-8')
|
msg = msg.decode('UTF-8')
|
||||||
return super(SassError, cls).__new__(cls, msg)
|
return super().__new__(cls, msg)
|
||||||
|
|
||||||
|
|
||||||
class SassWarning(collections.namedtuple('SassWarning', ('msg',))):
|
class SassWarning(collections.namedtuple('SassWarning', ('msg',))):
|
||||||
|
|
||||||
def __new__(cls, msg):
|
def __new__(cls, msg):
|
||||||
if not isinstance(msg, text_type):
|
if not isinstance(msg, str):
|
||||||
msg = msg.decode('UTF-8')
|
msg = msg.decode('UTF-8')
|
||||||
return super(SassWarning, cls).__new__(cls, msg)
|
return super().__new__(cls, msg)
|
||||||
|
|
||||||
|
|
||||||
class SassMap(collections_abc.Mapping):
|
class SassMap(collections.abc.Mapping):
|
||||||
"""Because sass maps can have mapping types as keys, we need an immutable
|
"""Because sass maps can have mapping types as keys, we need an immutable
|
||||||
hashable mapping type.
|
hashable mapping type.
|
||||||
|
|
||||||
|
@ -858,7 +845,7 @@ class SassMap(collections_abc.Mapping):
|
||||||
# Our interface
|
# Our interface
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '{}({})'.format(type(self).__name__, frozenset(self.items()))
|
return f'{type(self).__name__}({frozenset(self.items())})'
|
||||||
|
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
return self._hash
|
return self._hash
|
||||||
|
|
15
sassc.py
15
sassc.py
|
@ -1,15 +0,0 @@
|
||||||
import warnings
|
|
||||||
|
|
||||||
import pysassc
|
|
||||||
|
|
||||||
|
|
||||||
def main(*args, **kwargs):
|
|
||||||
warnings.warn(
|
|
||||||
'The `sassc` entrypoint is deprecated, please use `pysassc`',
|
|
||||||
FutureWarning,
|
|
||||||
),
|
|
||||||
return pysassc.main(*args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
exit(main())
|
|
191
sasstests.py
191
sasstests.py
|
@ -1,12 +1,10 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
import base64
|
import base64
|
||||||
|
import collections.abc
|
||||||
import contextlib
|
import contextlib
|
||||||
import functools
|
import functools
|
||||||
import glob
|
import glob
|
||||||
import json
|
|
||||||
import io
|
import io
|
||||||
import os
|
import json
|
||||||
import os.path
|
import os.path
|
||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
|
@ -17,15 +15,13 @@ import traceback
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from six import StringIO, b, string_types, text_type
|
|
||||||
from werkzeug.test import Client
|
from werkzeug.test import Client
|
||||||
from werkzeug.wrappers import Response
|
from werkzeug.wrappers import Response
|
||||||
|
|
||||||
import pysassc
|
import pysassc
|
||||||
import sass
|
import sass
|
||||||
import sassc
|
from sassutils.builder import build_directory
|
||||||
from sassutils._compat import collections_abc
|
from sassutils.builder import Manifest
|
||||||
from sassutils.builder import Manifest, build_directory
|
|
||||||
from sassutils.wsgi import SassMiddleware
|
from sassutils.wsgi import SassMiddleware
|
||||||
|
|
||||||
|
|
||||||
|
@ -71,7 +67,7 @@ A_EXPECTED_MAP = {
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
with io.open('test/a.scss', newline='') as f:
|
with open('test/a.scss', newline='') as f:
|
||||||
A_EXPECTED_MAP_CONTENTS = dict(A_EXPECTED_MAP, sourcesContent=[f.read()])
|
A_EXPECTED_MAP_CONTENTS = dict(A_EXPECTED_MAP, sourcesContent=[f.read()])
|
||||||
|
|
||||||
B_EXPECTED_CSS = '''\
|
B_EXPECTED_CSS = '''\
|
||||||
|
@ -95,7 +91,7 @@ h1 a {
|
||||||
color: green; }
|
color: green; }
|
||||||
'''
|
'''
|
||||||
|
|
||||||
D_EXPECTED_CSS = u'''\
|
D_EXPECTED_CSS = '''\
|
||||||
@charset "UTF-8";
|
@charset "UTF-8";
|
||||||
body {
|
body {
|
||||||
background-color: green; }
|
background-color: green; }
|
||||||
|
@ -103,7 +99,7 @@ body {
|
||||||
font: '나눔고딕', sans-serif; }
|
font: '나눔고딕', sans-serif; }
|
||||||
'''
|
'''
|
||||||
|
|
||||||
D_EXPECTED_CSS_WITH_MAP = u'''\
|
D_EXPECTED_CSS_WITH_MAP = '''\
|
||||||
@charset "UTF-8";
|
@charset "UTF-8";
|
||||||
body {
|
body {
|
||||||
background-color: green; }
|
background-color: green; }
|
||||||
|
@ -149,7 +145,7 @@ re_base64_data_uri = re.compile(r'^data:[^;]*?;base64,(.+)$')
|
||||||
def _map_in_output_dir(s):
|
def _map_in_output_dir(s):
|
||||||
def cb(match):
|
def cb(match):
|
||||||
filename = os.path.basename(match.group(1))
|
filename = os.path.basename(match.group(1))
|
||||||
return '/*# sourceMappingURL={} */'.format(filename)
|
return f'/*# sourceMappingURL={filename} */'
|
||||||
|
|
||||||
return re_sourcemap_url.sub(cb, s)
|
return re_sourcemap_url.sub(cb, s)
|
||||||
|
|
||||||
|
@ -163,9 +159,9 @@ def no_warnings(recwarn):
|
||||||
class BaseTestCase(unittest.TestCase):
|
class BaseTestCase(unittest.TestCase):
|
||||||
|
|
||||||
def assert_source_map_equal(self, expected, actual):
|
def assert_source_map_equal(self, expected, actual):
|
||||||
if isinstance(expected, string_types):
|
if isinstance(expected, str):
|
||||||
expected = json.loads(expected)
|
expected = json.loads(expected)
|
||||||
if isinstance(actual, string_types):
|
if isinstance(actual, str):
|
||||||
actual = json.loads(actual)
|
actual = json.loads(actual)
|
||||||
assert expected == actual
|
assert expected == actual
|
||||||
|
|
||||||
|
@ -175,7 +171,7 @@ class BaseTestCase(unittest.TestCase):
|
||||||
tree = json.load(f)
|
tree = json.load(f)
|
||||||
except ValueError as e: # pragma: no cover
|
except ValueError as e: # pragma: no cover
|
||||||
f.seek(0)
|
f.seek(0)
|
||||||
msg = '{!s}\n\n{}:\n\n{}'.format(e, filename, f.read())
|
msg = f'{e!s}\n\n{filename}:\n\n{f.read()}'
|
||||||
raise ValueError(msg)
|
raise ValueError(msg)
|
||||||
self.assert_source_map_equal(expected, tree)
|
self.assert_source_map_equal(expected, tree)
|
||||||
|
|
||||||
|
@ -196,7 +192,7 @@ class SassTestCase(BaseTestCase):
|
||||||
assert re.match(r'^\d+\.\d+\.\d+$', sass.__version__)
|
assert re.match(r'^\d+\.\d+\.\d+$', sass.__version__)
|
||||||
|
|
||||||
def test_output_styles(self):
|
def test_output_styles(self):
|
||||||
assert isinstance(sass.OUTPUT_STYLES, collections_abc.Mapping)
|
assert isinstance(sass.OUTPUT_STYLES, collections.abc.Mapping)
|
||||||
assert 'nested' in sass.OUTPUT_STYLES
|
assert 'nested' in sass.OUTPUT_STYLES
|
||||||
|
|
||||||
def test_and_join(self):
|
def test_and_join(self):
|
||||||
|
@ -294,9 +290,9 @@ a {
|
||||||
a b {
|
a b {
|
||||||
color: blue; }
|
color: blue; }
|
||||||
'''
|
'''
|
||||||
actual = sass.compile(string=u'a { color: blue; } /* 유니코드 */')
|
actual = sass.compile(string='a { color: blue; } /* 유니코드 */')
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
u'''@charset "UTF-8";
|
'''@charset "UTF-8";
|
||||||
a {
|
a {
|
||||||
color: blue; }
|
color: blue; }
|
||||||
|
|
||||||
|
@ -330,11 +326,11 @@ a {
|
||||||
def test_importer_one_arg(self):
|
def test_importer_one_arg(self):
|
||||||
"""Demonstrates one-arg importers + chaining."""
|
"""Demonstrates one-arg importers + chaining."""
|
||||||
def importer_returning_one_argument(path):
|
def importer_returning_one_argument(path):
|
||||||
assert type(path) is text_type
|
assert type(path) is str
|
||||||
return (
|
return (
|
||||||
# Trigger the import of an actual file
|
# Trigger the import of an actual file
|
||||||
('test/b.scss',),
|
('test/b.scss',),
|
||||||
(path, '.{0}-one-arg {{ color: blue; }}'.format(path)),
|
(path, f'.{path}-one-arg {{ color: blue; }}'),
|
||||||
)
|
)
|
||||||
|
|
||||||
ret = sass.compile(
|
ret = sass.compile(
|
||||||
|
@ -428,11 +424,11 @@ a {
|
||||||
path,
|
path,
|
||||||
'a { color: red; }',
|
'a { color: red; }',
|
||||||
json.dumps({
|
json.dumps({
|
||||||
"version": 3,
|
'version': 3,
|
||||||
"sources": [
|
'sources': [
|
||||||
path + ".db",
|
path + '.db',
|
||||||
],
|
],
|
||||||
"mappings": ";AAAA,CAAC,CAAC;EAAE,KAAK,EAAE,GAAI,GAAI",
|
'mappings': ';AAAA,CAAC,CAAC;EAAE,KAAK,EAAE,GAAI,GAAI',
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -448,17 +444,17 @@ a {
|
||||||
|
|
||||||
def test_importers_raises_exception(self):
|
def test_importers_raises_exception(self):
|
||||||
def importer(path):
|
def importer(path):
|
||||||
raise ValueError('Bad path: {}'.format(path))
|
raise ValueError(f'Bad path: {path}')
|
||||||
|
|
||||||
with assert_raises_compile_error(
|
with assert_raises_compile_error(
|
||||||
RegexMatcher(
|
RegexMatcher(
|
||||||
r'^Error: \n'
|
r'^Error: \n'
|
||||||
r' Traceback \(most recent call last\):\n'
|
r' Traceback \(most recent call last\):\n'
|
||||||
r'.+'
|
r'.+'
|
||||||
r'ValueError: Bad path: hi\n'
|
r'ValueError: Bad path: hi\n'
|
||||||
r' on line 1:9 of stdin\n'
|
r' on line 1:9 of stdin\n'
|
||||||
r'>> @import "hi";\n'
|
r'>> @import "hi";\n'
|
||||||
r' --------\^\n',
|
r' --------\^\n',
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
sass.compile(string='@import "hi";', importers=((0, importer),))
|
sass.compile(string='@import "hi";', importers=((0, importer),))
|
||||||
|
@ -469,14 +465,14 @@ a {
|
||||||
|
|
||||||
with assert_raises_compile_error(
|
with assert_raises_compile_error(
|
||||||
RegexMatcher(
|
RegexMatcher(
|
||||||
r'^Error: \n'
|
r'^Error: \n'
|
||||||
r' Traceback \(most recent call last\):\n'
|
r' Traceback \(most recent call last\):\n'
|
||||||
r'.+'
|
r'.+'
|
||||||
r'ValueError: Expected importer result to be a tuple of '
|
r'ValueError: Expected importer result to be a tuple of '
|
||||||
r'length \(1, 2, 3\) but got 0: \(\)\n'
|
r'length \(1, 2, 3\) but got 0: \(\)\n'
|
||||||
r' on line 1:9 of stdin\n'
|
r' on line 1:9 of stdin\n'
|
||||||
r'>> @import "hi";\n'
|
r'>> @import "hi";\n'
|
||||||
r' --------\^\n',
|
r' --------\^\n',
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
sass.compile(string='@import "hi";', importers=((0, importer),))
|
sass.compile(string='@import "hi";', importers=((0, importer),))
|
||||||
|
@ -487,14 +483,14 @@ a {
|
||||||
|
|
||||||
with assert_raises_compile_error(
|
with assert_raises_compile_error(
|
||||||
RegexMatcher(
|
RegexMatcher(
|
||||||
r'^Error: \n'
|
r'^Error: \n'
|
||||||
r' Traceback \(most recent call last\):\n'
|
r' Traceback \(most recent call last\):\n'
|
||||||
r'.+'
|
r'.+'
|
||||||
r'ValueError: Expected importer result to be a tuple of '
|
r'ValueError: Expected importer result to be a tuple of '
|
||||||
r"length \(1, 2, 3\) but got 4: \('a', 'b', 'c', 'd'\)\n"
|
r"length \(1, 2, 3\) but got 4: \('a', 'b', 'c', 'd'\)\n"
|
||||||
r' on line 1:9 of stdin\n'
|
r' on line 1:9 of stdin\n'
|
||||||
r'>> @import "hi";\n'
|
r'>> @import "hi";\n'
|
||||||
r' --------\^\n',
|
r' --------\^\n',
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
sass.compile(string='@import "hi";', importers=((0, importer),))
|
sass.compile(string='@import "hi";', importers=((0, importer),))
|
||||||
|
@ -640,31 +636,31 @@ class BuilderTestCase(BaseTestCase):
|
||||||
result_files = build_directory(self.sass_path, css_path)
|
result_files = build_directory(self.sass_path, css_path)
|
||||||
assert len(result_files) == 8
|
assert len(result_files) == 8
|
||||||
assert 'a.scss.css' == result_files['a.scss']
|
assert 'a.scss.css' == result_files['a.scss']
|
||||||
with io.open(
|
with open(
|
||||||
os.path.join(css_path, 'a.scss.css'), encoding='UTF-8',
|
os.path.join(css_path, 'a.scss.css'), encoding='UTF-8',
|
||||||
) as f:
|
) as f:
|
||||||
css = f.read()
|
css = f.read()
|
||||||
assert A_EXPECTED_CSS == css
|
assert A_EXPECTED_CSS == css
|
||||||
assert 'b.scss.css' == result_files['b.scss']
|
assert 'b.scss.css' == result_files['b.scss']
|
||||||
with io.open(
|
with open(
|
||||||
os.path.join(css_path, 'b.scss.css'), encoding='UTF-8',
|
os.path.join(css_path, 'b.scss.css'), encoding='UTF-8',
|
||||||
) as f:
|
) as f:
|
||||||
css = f.read()
|
css = f.read()
|
||||||
assert B_EXPECTED_CSS == css
|
assert B_EXPECTED_CSS == css
|
||||||
assert 'c.scss.css' == result_files['c.scss']
|
assert 'c.scss.css' == result_files['c.scss']
|
||||||
with io.open(
|
with open(
|
||||||
os.path.join(css_path, 'c.scss.css'), encoding='UTF-8',
|
os.path.join(css_path, 'c.scss.css'), encoding='UTF-8',
|
||||||
) as f:
|
) as f:
|
||||||
css = f.read()
|
css = f.read()
|
||||||
assert C_EXPECTED_CSS == css
|
assert C_EXPECTED_CSS == css
|
||||||
assert 'd.scss.css' == result_files['d.scss']
|
assert 'd.scss.css' == result_files['d.scss']
|
||||||
with io.open(
|
with open(
|
||||||
os.path.join(css_path, 'd.scss.css'), encoding='UTF-8',
|
os.path.join(css_path, 'd.scss.css'), encoding='UTF-8',
|
||||||
) as f:
|
) as f:
|
||||||
css = f.read()
|
css = f.read()
|
||||||
assert D_EXPECTED_CSS == css
|
assert D_EXPECTED_CSS == css
|
||||||
assert 'e.scss.css' == result_files['e.scss']
|
assert 'e.scss.css' == result_files['e.scss']
|
||||||
with io.open(
|
with open(
|
||||||
os.path.join(css_path, 'e.scss.css'), encoding='UTF-8',
|
os.path.join(css_path, 'e.scss.css'), encoding='UTF-8',
|
||||||
) as f:
|
) as f:
|
||||||
css = f.read()
|
css = f.read()
|
||||||
|
@ -673,7 +669,7 @@ class BuilderTestCase(BaseTestCase):
|
||||||
os.path.join('subdir', 'recur.scss.css'),
|
os.path.join('subdir', 'recur.scss.css'),
|
||||||
result_files[os.path.join('subdir', 'recur.scss')],
|
result_files[os.path.join('subdir', 'recur.scss')],
|
||||||
)
|
)
|
||||||
with io.open(
|
with open(
|
||||||
os.path.join(css_path, 'g.scss.css'), encoding='UTF-8',
|
os.path.join(css_path, 'g.scss.css'), encoding='UTF-8',
|
||||||
) as f:
|
) as f:
|
||||||
css = f.read()
|
css = f.read()
|
||||||
|
@ -683,12 +679,12 @@ class BuilderTestCase(BaseTestCase):
|
||||||
result_files[os.path.join('subdir', 'recur.scss')],
|
result_files[os.path.join('subdir', 'recur.scss')],
|
||||||
)
|
)
|
||||||
assert 'h.sass.css' == result_files['h.sass']
|
assert 'h.sass.css' == result_files['h.sass']
|
||||||
with io.open(
|
with open(
|
||||||
os.path.join(css_path, 'h.sass.css'), encoding='UTF-8',
|
os.path.join(css_path, 'h.sass.css'), encoding='UTF-8',
|
||||||
) as f:
|
) as f:
|
||||||
css = f.read()
|
css = f.read()
|
||||||
assert H_EXPECTED_CSS == css
|
assert H_EXPECTED_CSS == css
|
||||||
with io.open(
|
with open(
|
||||||
os.path.join(css_path, 'subdir', 'recur.scss.css'),
|
os.path.join(css_path, 'subdir', 'recur.scss.css'),
|
||||||
encoding='UTF-8',
|
encoding='UTF-8',
|
||||||
) as f:
|
) as f:
|
||||||
|
@ -703,7 +699,7 @@ class BuilderTestCase(BaseTestCase):
|
||||||
)
|
)
|
||||||
assert len(result_files) == 8
|
assert len(result_files) == 8
|
||||||
assert 'a.scss.css' == result_files['a.scss']
|
assert 'a.scss.css' == result_files['a.scss']
|
||||||
with io.open(
|
with open(
|
||||||
os.path.join(css_path, 'a.scss.css'), encoding='UTF-8',
|
os.path.join(css_path, 'a.scss.css'), encoding='UTF-8',
|
||||||
) as f:
|
) as f:
|
||||||
css = f.read()
|
css = f.read()
|
||||||
|
@ -755,7 +751,7 @@ class ManifestTestCase(BaseTestCase):
|
||||||
with open(os.path.join(d, 'css', 'a.scss.css')) as f:
|
with open(os.path.join(d, 'css', 'a.scss.css')) as f:
|
||||||
assert A_EXPECTED_CSS == f.read()
|
assert A_EXPECTED_CSS == f.read()
|
||||||
m.build_one(d, 'b.scss', source_map=True)
|
m.build_one(d, 'b.scss', source_map=True)
|
||||||
with io.open(
|
with open(
|
||||||
os.path.join(d, 'css', 'b.scss.css'), encoding='UTF-8',
|
os.path.join(d, 'css', 'b.scss.css'), encoding='UTF-8',
|
||||||
) as f:
|
) as f:
|
||||||
assert f.read() == _map_in_output_dir(B_EXPECTED_CSS_WITH_MAP)
|
assert f.read() == _map_in_output_dir(B_EXPECTED_CSS_WITH_MAP)
|
||||||
|
@ -773,7 +769,7 @@ class ManifestTestCase(BaseTestCase):
|
||||||
os.path.join(d, 'css', 'b.scss.css.map'),
|
os.path.join(d, 'css', 'b.scss.css.map'),
|
||||||
)
|
)
|
||||||
m.build_one(d, 'd.scss', source_map=True)
|
m.build_one(d, 'd.scss', source_map=True)
|
||||||
with io.open(
|
with open(
|
||||||
os.path.join(d, 'css', 'd.scss.css'), encoding='UTF-8',
|
os.path.join(d, 'css', 'd.scss.css'), encoding='UTF-8',
|
||||||
) as f:
|
) as f:
|
||||||
assert f.read() == _map_in_output_dir(D_EXPECTED_CSS_WITH_MAP)
|
assert f.read() == _map_in_output_dir(D_EXPECTED_CSS_WITH_MAP)
|
||||||
|
@ -838,7 +834,7 @@ class WsgiTestCase(BaseTestCase):
|
||||||
r = client.get('/static/a.scss.css')
|
r = client.get('/static/a.scss.css')
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
b(_map_in_output_dir(A_EXPECTED_CSS_WITH_MAP)),
|
_map_in_output_dir(A_EXPECTED_CSS_WITH_MAP).encode(),
|
||||||
r.data,
|
r.data,
|
||||||
)
|
)
|
||||||
assert r.mimetype == 'text/css'
|
assert r.mimetype == 'text/css'
|
||||||
|
@ -903,7 +899,7 @@ class DistutilsTestCase(BaseTestCase):
|
||||||
return os.path.join(
|
return os.path.join(
|
||||||
os.path.dirname(__file__),
|
os.path.dirname(__file__),
|
||||||
'testpkg', 'testpkg', 'static', 'css',
|
'testpkg', 'testpkg', 'static', 'css',
|
||||||
*args
|
*args,
|
||||||
)
|
)
|
||||||
|
|
||||||
def list_built_css(self):
|
def list_built_css(self):
|
||||||
|
@ -942,8 +938,8 @@ class DistutilsTestCase(BaseTestCase):
|
||||||
class SasscTestCase(BaseTestCase):
|
class SasscTestCase(BaseTestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.out = StringIO()
|
self.out = io.StringIO()
|
||||||
self.err = StringIO()
|
self.err = io.StringIO()
|
||||||
|
|
||||||
def test_no_args(self):
|
def test_no_args(self):
|
||||||
exit_code = pysassc.main(['pysassc'], self.out, self.err)
|
exit_code = pysassc.main(['pysassc'], self.out, self.err)
|
||||||
|
@ -973,17 +969,6 @@ class SasscTestCase(BaseTestCase):
|
||||||
assert self.err.getvalue() == ''
|
assert self.err.getvalue() == ''
|
||||||
assert A_EXPECTED_CSS.strip() == self.out.getvalue().strip()
|
assert A_EXPECTED_CSS.strip() == self.out.getvalue().strip()
|
||||||
|
|
||||||
def test_sassc_stdout(self):
|
|
||||||
with pytest.warns(FutureWarning) as warninfo:
|
|
||||||
exit_code = sassc.main(
|
|
||||||
['sassc', 'test/a.scss'],
|
|
||||||
self.out, self.err,
|
|
||||||
)
|
|
||||||
assert 'use `pysassc`' in warninfo[0].message.args[0]
|
|
||||||
assert exit_code == 0
|
|
||||||
assert self.err.getvalue() == ''
|
|
||||||
assert A_EXPECTED_CSS.strip() == self.out.getvalue().strip()
|
|
||||||
|
|
||||||
def test_pysassc_output(self):
|
def test_pysassc_output(self):
|
||||||
fd, tmp = tempfile.mkstemp('.css')
|
fd, tmp = tempfile.mkstemp('.css')
|
||||||
try:
|
try:
|
||||||
|
@ -995,7 +980,7 @@ class SasscTestCase(BaseTestCase):
|
||||||
assert exit_code == 0
|
assert exit_code == 0
|
||||||
assert self.err.getvalue() == ''
|
assert self.err.getvalue() == ''
|
||||||
assert self.out.getvalue() == ''
|
assert self.out.getvalue() == ''
|
||||||
with io.open(tmp, encoding='UTF-8', newline='') as f:
|
with open(tmp, encoding='UTF-8', newline='') as f:
|
||||||
assert A_EXPECTED_CSS.strip() == f.read().strip()
|
assert A_EXPECTED_CSS.strip() == f.read().strip()
|
||||||
finally:
|
finally:
|
||||||
os.remove(tmp)
|
os.remove(tmp)
|
||||||
|
@ -1011,7 +996,7 @@ class SasscTestCase(BaseTestCase):
|
||||||
assert exit_code == 0
|
assert exit_code == 0
|
||||||
assert self.err.getvalue() == ''
|
assert self.err.getvalue() == ''
|
||||||
assert self.out.getvalue() == ''
|
assert self.out.getvalue() == ''
|
||||||
with io.open(tmp, encoding='UTF-8') as f:
|
with open(tmp, encoding='UTF-8') as f:
|
||||||
assert D_EXPECTED_CSS.strip() == f.read().strip()
|
assert D_EXPECTED_CSS.strip() == f.read().strip()
|
||||||
finally:
|
finally:
|
||||||
os.remove(tmp)
|
os.remove(tmp)
|
||||||
|
@ -1093,10 +1078,10 @@ class CompileDirectoriesTest(unittest.TestCase):
|
||||||
input_dir = os.path.join(tmpdir, 'input')
|
input_dir = os.path.join(tmpdir, 'input')
|
||||||
output_dir = os.path.join(tmpdir, 'output')
|
output_dir = os.path.join(tmpdir, 'output')
|
||||||
os.makedirs(input_dir)
|
os.makedirs(input_dir)
|
||||||
with io.open(
|
with open(
|
||||||
os.path.join(input_dir, 'test.scss'), 'w', encoding='UTF-8',
|
os.path.join(input_dir, 'test.scss'), 'w', encoding='UTF-8',
|
||||||
) as f:
|
) as f:
|
||||||
f.write(u'a { content: "☃"; }')
|
f.write('a { content: "☃"; }')
|
||||||
# Raised a UnicodeEncodeError in py2 before #82 (issue #72)
|
# Raised a UnicodeEncodeError in py2 before #82 (issue #72)
|
||||||
# Also raised a UnicodeEncodeError in py3 if the default encoding
|
# Also raised a UnicodeEncodeError in py3 if the default encoding
|
||||||
# couldn't represent it (such as cp1252 on windows)
|
# couldn't represent it (such as cp1252 on windows)
|
||||||
|
@ -1131,7 +1116,7 @@ class CompileDirectoriesTest(unittest.TestCase):
|
||||||
class SassFunctionTest(unittest.TestCase):
|
class SassFunctionTest(unittest.TestCase):
|
||||||
|
|
||||||
def test_from_lambda(self):
|
def test_from_lambda(self):
|
||||||
lambda_ = lambda abc, d: None # pragma: no branch # noqa: E731
|
def lambda_(abc, d): return None # pragma: no branch # noqa: E731
|
||||||
sf = sass.SassFunction.from_lambda('func_name', lambda_)
|
sf = sass.SassFunction.from_lambda('func_name', lambda_)
|
||||||
assert 'func_name' == sf.name
|
assert 'func_name' == sf.name
|
||||||
assert ('$abc', '$d') == sf.arguments
|
assert ('$abc', '$d') == sf.arguments
|
||||||
|
@ -1164,14 +1149,14 @@ def test_sass_func_type_errors(func):
|
||||||
|
|
||||||
class SassTypesTest(unittest.TestCase):
|
class SassTypesTest(unittest.TestCase):
|
||||||
def test_number_no_conversion(self):
|
def test_number_no_conversion(self):
|
||||||
num = sass.SassNumber(123., u'px')
|
num = sass.SassNumber(123., 'px')
|
||||||
assert type(num.value) is float, type(num.value)
|
assert type(num.value) is float, type(num.value)
|
||||||
assert type(num.unit) is text_type, type(num.unit)
|
assert type(num.unit) is str, type(num.unit)
|
||||||
|
|
||||||
def test_number_conversion(self):
|
def test_number_conversion(self):
|
||||||
num = sass.SassNumber(123, b'px')
|
num = sass.SassNumber(123, b'px')
|
||||||
assert type(num.value) is float, type(num.value)
|
assert type(num.value) is float, type(num.value)
|
||||||
assert type(num.unit) is text_type, type(num.unit)
|
assert type(num.unit) is str, type(num.unit)
|
||||||
|
|
||||||
def test_color_no_conversion(self):
|
def test_color_no_conversion(self):
|
||||||
color = sass.SassColor(1., 2., 3., .5)
|
color = sass.SassColor(1., 2., 3., .5)
|
||||||
|
@ -1198,20 +1183,20 @@ class SassTypesTest(unittest.TestCase):
|
||||||
assert lst.separator is sass.SASS_SEPARATOR_SPACE, lst.separator
|
assert lst.separator is sass.SASS_SEPARATOR_SPACE, lst.separator
|
||||||
|
|
||||||
def test_sass_warning_no_conversion(self):
|
def test_sass_warning_no_conversion(self):
|
||||||
warn = sass.SassWarning(u'error msg')
|
warn = sass.SassWarning('error msg')
|
||||||
assert type(warn.msg) is text_type, type(warn.msg)
|
assert type(warn.msg) is str, type(warn.msg)
|
||||||
|
|
||||||
def test_sass_warning_no_conversion_bytes_message(self):
|
def test_sass_warning_no_conversion_bytes_message(self):
|
||||||
warn = sass.SassWarning(b'error msg')
|
warn = sass.SassWarning(b'error msg')
|
||||||
assert type(warn.msg) is text_type, type(warn.msg)
|
assert type(warn.msg) is str, type(warn.msg)
|
||||||
|
|
||||||
def test_sass_error_no_conversion(self):
|
def test_sass_error_no_conversion(self):
|
||||||
err = sass.SassError(u'error msg')
|
err = sass.SassError('error msg')
|
||||||
assert type(err.msg) is text_type, type(err.msg)
|
assert type(err.msg) is str, type(err.msg)
|
||||||
|
|
||||||
def test_sass_error_conversion(self):
|
def test_sass_error_conversion(self):
|
||||||
err = sass.SassError(b'error msg')
|
err = sass.SassError(b'error msg')
|
||||||
assert type(err.msg) is text_type, type(err.msg)
|
assert type(err.msg) is str, type(err.msg)
|
||||||
|
|
||||||
|
|
||||||
def raises():
|
def raises():
|
||||||
|
@ -1244,11 +1229,11 @@ def returns_none():
|
||||||
|
|
||||||
|
|
||||||
def returns_unicode():
|
def returns_unicode():
|
||||||
return u'☃'
|
return '☃'
|
||||||
|
|
||||||
|
|
||||||
def returns_bytes():
|
def returns_bytes():
|
||||||
return u'☃'.encode('UTF-8')
|
return '☃'.encode()
|
||||||
|
|
||||||
|
|
||||||
def returns_number():
|
def returns_number():
|
||||||
|
@ -1380,7 +1365,7 @@ def assert_raises_compile_error(expected):
|
||||||
assert msg == expected, (msg, expected)
|
assert msg == expected, (msg, expected)
|
||||||
|
|
||||||
|
|
||||||
class RegexMatcher(object):
|
class RegexMatcher:
|
||||||
def __init__(self, reg, flags=None):
|
def __init__(self, reg, flags=None):
|
||||||
self.reg = re.compile(reg, re.MULTILINE | re.DOTALL)
|
self.reg = re.compile(reg, re.MULTILINE | re.DOTALL)
|
||||||
|
|
||||||
|
@ -1393,14 +1378,14 @@ class CustomFunctionsTest(unittest.TestCase):
|
||||||
def test_raises(self):
|
def test_raises(self):
|
||||||
with assert_raises_compile_error(
|
with assert_raises_compile_error(
|
||||||
RegexMatcher(
|
RegexMatcher(
|
||||||
r'^Error: error in C function raises: \n'
|
r'^Error: error in C function raises: \n'
|
||||||
r' Traceback \(most recent call last\):\n'
|
r' Traceback \(most recent call last\):\n'
|
||||||
r'.+'
|
r'.+'
|
||||||
r'AssertionError: foo\n'
|
r'AssertionError: foo\n'
|
||||||
r' on line 1:14 of stdin, in function `raises`\n'
|
r' on line 1:14 of stdin, in function `raises`\n'
|
||||||
r' from line 1:14 of stdin\n'
|
r' from line 1:14 of stdin\n'
|
||||||
r'>> a { content: raises\(\); }\n'
|
r'>> a { content: raises\(\); }\n'
|
||||||
r' -------------\^\n$',
|
r' -------------\^\n$',
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
compile_with_func('a { content: raises(); }')
|
compile_with_func('a { content: raises(); }')
|
||||||
|
@ -1472,13 +1457,13 @@ class CustomFunctionsTest(unittest.TestCase):
|
||||||
def test_unicode(self):
|
def test_unicode(self):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
compile_with_func('a { content: returns_unicode(); }'),
|
compile_with_func('a { content: returns_unicode(); }'),
|
||||||
u'\ufeffa{content:☃}\n',
|
'\ufeffa{content:☃}\n',
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_bytes(self):
|
def test_bytes(self):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
compile_with_func('a { content: returns_bytes(); }'),
|
compile_with_func('a { content: returns_bytes(); }'),
|
||||||
u'\ufeffa{content:☃}\n',
|
'\ufeffa{content:☃}\n',
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_number(self):
|
def test_number(self):
|
||||||
|
@ -1550,7 +1535,7 @@ class CustomFunctionsTest(unittest.TestCase):
|
||||||
def test_identity_strings(self):
|
def test_identity_strings(self):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
compile_with_func('a { content: identity(returns_unicode()); }'),
|
compile_with_func('a { content: identity(returns_unicode()); }'),
|
||||||
u'\ufeffa{content:☃}\n',
|
'\ufeffa{content:☃}\n',
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_identity_number(self):
|
def test_identity_number(self):
|
||||||
|
@ -1626,7 +1611,7 @@ class CustomFunctionsTest(unittest.TestCase):
|
||||||
|
|
||||||
def test_stack_trace_formatting():
|
def test_stack_trace_formatting():
|
||||||
try:
|
try:
|
||||||
sass.compile(string=u'a{☃')
|
sass.compile(string='a{☃')
|
||||||
raise AssertionError('expected to raise CompileError')
|
raise AssertionError('expected to raise CompileError')
|
||||||
except sass.CompileError:
|
except sass.CompileError:
|
||||||
tb = traceback.format_exc()
|
tb = traceback.format_exc()
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
from six import PY2
|
|
||||||
|
|
||||||
|
|
||||||
if PY2: # pragma: no cover (PY2)
|
|
||||||
import collections as collections_abc # noqa: F401
|
|
||||||
else: # pragma: no cover (PY3)
|
|
||||||
import collections.abc as collections_abc # noqa: F401
|
|
|
@ -2,17 +2,12 @@
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
import collections.abc
|
||||||
import io
|
|
||||||
import os
|
|
||||||
import os.path
|
import os.path
|
||||||
import re
|
import re
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
from six import string_types
|
|
||||||
|
|
||||||
from sass import compile
|
from sass import compile
|
||||||
from sassutils._compat import collections_abc
|
|
||||||
|
|
||||||
__all__ = 'SUFFIXES', 'SUFFIX_PATTERN', 'Manifest', 'build_directory'
|
__all__ = 'SUFFIXES', 'SUFFIX_PATTERN', 'Manifest', 'build_directory'
|
||||||
|
|
||||||
|
@ -69,7 +64,7 @@ def build_directory(
|
||||||
output_style=output_style,
|
output_style=output_style,
|
||||||
include_paths=[_root_sass],
|
include_paths=[_root_sass],
|
||||||
)
|
)
|
||||||
with io.open(
|
with open(
|
||||||
css_fullname, 'w', encoding='utf-8', newline='',
|
css_fullname, 'w', encoding='utf-8', newline='',
|
||||||
) as css_file:
|
) as css_file:
|
||||||
css_file.write(css)
|
css_file.write(css)
|
||||||
|
@ -88,7 +83,7 @@ def build_directory(
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
class Manifest(object):
|
class Manifest:
|
||||||
"""Building manifest of Sass/SCSS.
|
"""Building manifest of Sass/SCSS.
|
||||||
|
|
||||||
:param sass_path: the path of the directory that contains Sass/SCSS
|
:param sass_path: the path of the directory that contains Sass/SCSS
|
||||||
|
@ -105,7 +100,7 @@ class Manifest(object):
|
||||||
def normalize_manifests(cls, manifests):
|
def normalize_manifests(cls, manifests):
|
||||||
if manifests is None:
|
if manifests is None:
|
||||||
manifests = {}
|
manifests = {}
|
||||||
elif isinstance(manifests, collections_abc.Mapping):
|
elif isinstance(manifests, collections.abc.Mapping):
|
||||||
manifests = dict(manifests)
|
manifests = dict(manifests)
|
||||||
else:
|
else:
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
|
@ -113,7 +108,7 @@ class Manifest(object):
|
||||||
repr(manifests),
|
repr(manifests),
|
||||||
)
|
)
|
||||||
for package_name, manifest in manifests.items():
|
for package_name, manifest in manifests.items():
|
||||||
if not isinstance(package_name, string_types):
|
if not isinstance(package_name, str):
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
'manifest keys must be a string of package '
|
'manifest keys must be a string of package '
|
||||||
'name, not ' + repr(package_name),
|
'name, not ' + repr(package_name),
|
||||||
|
@ -122,9 +117,9 @@ class Manifest(object):
|
||||||
continue
|
continue
|
||||||
elif isinstance(manifest, tuple):
|
elif isinstance(manifest, tuple):
|
||||||
manifest = Manifest(*manifest)
|
manifest = Manifest(*manifest)
|
||||||
elif isinstance(manifest, collections_abc.Mapping):
|
elif isinstance(manifest, collections.abc.Mapping):
|
||||||
manifest = Manifest(**manifest)
|
manifest = Manifest(**manifest)
|
||||||
elif isinstance(manifest, string_types):
|
elif isinstance(manifest, str):
|
||||||
manifest = Manifest(manifest)
|
manifest = Manifest(manifest)
|
||||||
else:
|
else:
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
|
@ -142,21 +137,21 @@ class Manifest(object):
|
||||||
wsgi_path=None,
|
wsgi_path=None,
|
||||||
strip_extension=None,
|
strip_extension=None,
|
||||||
):
|
):
|
||||||
if not isinstance(sass_path, string_types):
|
if not isinstance(sass_path, str):
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
'sass_path must be a string, not ' +
|
'sass_path must be a string, not ' +
|
||||||
repr(sass_path),
|
repr(sass_path),
|
||||||
)
|
)
|
||||||
if css_path is None:
|
if css_path is None:
|
||||||
css_path = sass_path
|
css_path = sass_path
|
||||||
elif not isinstance(css_path, string_types):
|
elif not isinstance(css_path, str):
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
'css_path must be a string, not ' +
|
'css_path must be a string, not ' +
|
||||||
repr(css_path),
|
repr(css_path),
|
||||||
)
|
)
|
||||||
if wsgi_path is None:
|
if wsgi_path is None:
|
||||||
wsgi_path = css_path
|
wsgi_path = css_path
|
||||||
elif not isinstance(wsgi_path, string_types):
|
elif not isinstance(wsgi_path, str):
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
'wsgi_path must be a string, not ' +
|
'wsgi_path must be a string, not ' +
|
||||||
repr(wsgi_path),
|
repr(wsgi_path),
|
||||||
|
@ -292,11 +287,11 @@ class Manifest(object):
|
||||||
css_folder = os.path.dirname(css_path)
|
css_folder = os.path.dirname(css_path)
|
||||||
if not os.path.exists(css_folder):
|
if not os.path.exists(css_folder):
|
||||||
os.makedirs(css_folder)
|
os.makedirs(css_folder)
|
||||||
with io.open(css_path, 'w', encoding='utf-8', newline='') as f:
|
with open(css_path, 'w', encoding='utf-8', newline='') as f:
|
||||||
f.write(css)
|
f.write(css)
|
||||||
if source_map:
|
if source_map:
|
||||||
# Source maps are JSON, and JSON has to be UTF-8 encoded
|
# Source maps are JSON, and JSON has to be UTF-8 encoded
|
||||||
with io.open(
|
with open(
|
||||||
source_map_path, 'w', encoding='utf-8', newline='',
|
source_map_path, 'w', encoding='utf-8', newline='',
|
||||||
) as f:
|
) as f:
|
||||||
f.write(source_map)
|
f.write(source_map)
|
||||||
|
|
|
@ -67,19 +67,17 @@ The option can also be a mapping of package names to manifest dictionaries::
|
||||||
Added ``--output-style``/``-s`` option to :class:`build_sass` command.
|
Added ``--output-style``/``-s`` option to :class:`build_sass` command.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from __future__ import absolute_import
|
import functools
|
||||||
|
import os.path
|
||||||
|
|
||||||
import distutils.errors
|
import distutils.errors
|
||||||
import distutils.log
|
import distutils.log
|
||||||
import distutils.util
|
import distutils.util
|
||||||
import functools
|
|
||||||
import os.path
|
|
||||||
|
|
||||||
from setuptools import Command
|
from setuptools import Command
|
||||||
from setuptools.command.sdist import sdist
|
from setuptools.command.sdist import sdist
|
||||||
|
|
||||||
from sass import OUTPUT_STYLES
|
|
||||||
from .builder import Manifest
|
from .builder import Manifest
|
||||||
|
from sass import OUTPUT_STYLES
|
||||||
|
|
||||||
__all__ = 'build_sass', 'validate_manifests'
|
__all__ = 'build_sass', 'validate_manifests'
|
||||||
|
|
||||||
|
|
|
@ -2,22 +2,19 @@
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from __future__ import absolute_import
|
import collections.abc
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
from pkg_resources import resource_filename
|
from pkg_resources import resource_filename
|
||||||
|
|
||||||
from sass import CompileError
|
|
||||||
from sassutils._compat import collections_abc
|
|
||||||
from .builder import Manifest
|
from .builder import Manifest
|
||||||
|
from sass import CompileError
|
||||||
|
|
||||||
__all__ = 'SassMiddleware',
|
__all__ = 'SassMiddleware',
|
||||||
|
|
||||||
|
|
||||||
class SassMiddleware(object):
|
class SassMiddleware:
|
||||||
r"""WSGI middleware for development purpose. Every time a CSS file has
|
r"""WSGI middleware for development purpose. Every time a CSS file has
|
||||||
requested it finds a matched Sass/SCSS source file and then compiled
|
requested it finds a matched Sass/SCSS source file and then compiled
|
||||||
it into CSS.
|
it into CSS.
|
||||||
|
@ -100,7 +97,7 @@ class SassMiddleware(object):
|
||||||
)
|
)
|
||||||
self.app = app
|
self.app = app
|
||||||
self.manifests = Manifest.normalize_manifests(manifests)
|
self.manifests = Manifest.normalize_manifests(manifests)
|
||||||
if not isinstance(package_dir, collections_abc.Mapping):
|
if not isinstance(package_dir, collections.abc.Mapping):
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
'package_dir must be a mapping object, not ' +
|
'package_dir must be a mapping object, not ' +
|
||||||
repr(package_dir),
|
repr(package_dir),
|
||||||
|
@ -138,7 +135,7 @@ class SassMiddleware(object):
|
||||||
sass_filename,
|
sass_filename,
|
||||||
source_map=True,
|
source_map=True,
|
||||||
)
|
)
|
||||||
except (IOError, OSError):
|
except OSError:
|
||||||
break
|
break
|
||||||
except CompileError as e:
|
except CompileError as e:
|
||||||
logger = logging.getLogger(__name__ + '.SassMiddleware')
|
logger = logging.getLogger(__name__ + '.SassMiddleware')
|
||||||
|
|
27
setup.py
27
setup.py
|
@ -1,11 +1,5 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
import ast
|
import ast
|
||||||
import atexit
|
import atexit
|
||||||
import distutils.cmd
|
|
||||||
import distutils.log
|
|
||||||
import distutils.sysconfig
|
|
||||||
import os.path
|
import os.path
|
||||||
import platform
|
import platform
|
||||||
import shutil
|
import shutil
|
||||||
|
@ -13,7 +7,11 @@ import subprocess
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
from setuptools import Extension, setup
|
import distutils.cmd
|
||||||
|
import distutils.log
|
||||||
|
import distutils.sysconfig
|
||||||
|
from setuptools import Extension
|
||||||
|
from setuptools import setup
|
||||||
|
|
||||||
MACOS_FLAG = ['-mmacosx-version-min=10.7']
|
MACOS_FLAG = ['-mmacosx-version-min=10.7']
|
||||||
FLAGS_POSIX = [
|
FLAGS_POSIX = [
|
||||||
|
@ -83,9 +81,9 @@ else:
|
||||||
libsass_version = libsass_version_file.read().decode('UTF-8').strip()
|
libsass_version = libsass_version_file.read().decode('UTF-8').strip()
|
||||||
if sys.platform == 'win32':
|
if sys.platform == 'win32':
|
||||||
# This looks wrong, but is required for some reason :(
|
# This looks wrong, but is required for some reason :(
|
||||||
define = r'/DLIBSASS_VERSION="\"{}\""'.format(libsass_version)
|
define = fr'/DLIBSASS_VERSION="\"{libsass_version}\""'
|
||||||
else:
|
else:
|
||||||
define = '-DLIBSASS_VERSION="{}"'.format(libsass_version)
|
define = f'-DLIBSASS_VERSION="{libsass_version}"'
|
||||||
|
|
||||||
for directory in (
|
for directory in (
|
||||||
os.path.join('libsass', 'src'),
|
os.path.join('libsass', 'src'),
|
||||||
|
@ -185,7 +183,7 @@ def readme():
|
||||||
try:
|
try:
|
||||||
with open(os.path.join(os.path.dirname(__file__), 'README.rst')) as f:
|
with open(os.path.join(os.path.dirname(__file__), 'README.rst')) as f:
|
||||||
return f.read()
|
return f.read()
|
||||||
except IOError:
|
except OSError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@ -232,7 +230,7 @@ if sys.version_info >= (3,) and platform.python_implementation() == 'CPython':
|
||||||
else:
|
else:
|
||||||
class bdist_wheel(wheel.bdist_wheel.bdist_wheel):
|
class bdist_wheel(wheel.bdist_wheel.bdist_wheel):
|
||||||
def finalize_options(self):
|
def finalize_options(self):
|
||||||
self.py_limited_api = 'cp3{}'.format(sys.version_info[1])
|
self.py_limited_api = f'cp3{sys.version_info[1]}'
|
||||||
super().finalize_options()
|
super().finalize_options()
|
||||||
|
|
||||||
cmdclass['bdist_wheel'] = bdist_wheel
|
cmdclass['bdist_wheel'] = bdist_wheel
|
||||||
|
@ -246,7 +244,7 @@ setup(
|
||||||
version=version(),
|
version=version(),
|
||||||
ext_modules=[sass_extension],
|
ext_modules=[sass_extension],
|
||||||
packages=['sassutils'],
|
packages=['sassutils'],
|
||||||
py_modules=['pysassc', 'sass', 'sassc', 'sasstests'],
|
py_modules=['pysassc', 'sass', 'sasstests'],
|
||||||
package_data={
|
package_data={
|
||||||
'': [
|
'': [
|
||||||
'README.rst',
|
'README.rst',
|
||||||
|
@ -267,11 +265,8 @@ setup(
|
||||||
],
|
],
|
||||||
'console_scripts': [
|
'console_scripts': [
|
||||||
['pysassc = pysassc:main'],
|
['pysassc = pysassc:main'],
|
||||||
# TODO: remove `sassc` entry (#134)
|
|
||||||
['sassc = sassc:main'],
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
install_requires=['six'],
|
|
||||||
classifiers=[
|
classifiers=[
|
||||||
'Development Status :: 5 - Production/Stable',
|
'Development Status :: 5 - Production/Stable',
|
||||||
'Environment :: Web Environment',
|
'Environment :: Web Environment',
|
||||||
|
@ -280,7 +275,6 @@ setup(
|
||||||
'Operating System :: OS Independent',
|
'Operating System :: OS Independent',
|
||||||
'Programming Language :: C',
|
'Programming Language :: C',
|
||||||
'Programming Language :: C++',
|
'Programming Language :: C++',
|
||||||
'Programming Language :: Python :: 2.7',
|
|
||||||
'Programming Language :: Python :: 3',
|
'Programming Language :: Python :: 3',
|
||||||
'Programming Language :: Python :: 3.6',
|
'Programming Language :: Python :: 3.6',
|
||||||
'Programming Language :: Python :: 3.7',
|
'Programming Language :: Python :: 3.7',
|
||||||
|
@ -294,5 +288,6 @@ setup(
|
||||||
'Topic :: Software Development :: Code Generators',
|
'Topic :: Software Development :: Code Generators',
|
||||||
'Topic :: Software Development :: Compilers',
|
'Topic :: Software Development :: Compilers',
|
||||||
],
|
],
|
||||||
|
python_requires='>=3.6',
|
||||||
cmdclass=cmdclass,
|
cmdclass=cmdclass,
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue