commit
c92fb3c494
112
fastentrypoints.py
Normal file
112
fastentrypoints.py
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
# noqa: D300,D400
|
||||||
|
# Copyright (c) 2016, Aaron Christianson
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are
|
||||||
|
# met:
|
||||||
|
#
|
||||||
|
# 1. Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
#
|
||||||
|
# 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer in the
|
||||||
|
# documentation and/or other materials provided with the distribution.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||||
|
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||||
|
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||||
|
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
'''
|
||||||
|
Monkey patch setuptools to write faster console_scripts with this format:
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from mymodule import entry_function
|
||||||
|
sys.exit(entry_function())
|
||||||
|
|
||||||
|
This is better.
|
||||||
|
|
||||||
|
(c) 2016, Aaron Christianson
|
||||||
|
http://github.com/ninjaaron/fast-entry_points
|
||||||
|
'''
|
||||||
|
from setuptools.command import easy_install
|
||||||
|
import re
|
||||||
|
TEMPLATE = '''\
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# EASY-INSTALL-ENTRY-SCRIPT: '{3}','{4}','{5}'
|
||||||
|
__requires__ = '{3}'
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from {0} import {1}
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
|
||||||
|
sys.exit({2}())'''
|
||||||
|
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_args(cls, dist, header=None): # noqa: D205,D400
|
||||||
|
"""
|
||||||
|
Yield write_script() argument tuples for a distribution's
|
||||||
|
console_scripts and gui_scripts entry points.
|
||||||
|
"""
|
||||||
|
if header is None:
|
||||||
|
# pylint: disable=E1101
|
||||||
|
header = cls.get_header()
|
||||||
|
spec = str(dist.as_requirement())
|
||||||
|
for type_ in 'console', 'gui':
|
||||||
|
group = type_ + '_scripts'
|
||||||
|
for name, ep in dist.get_entry_map(group).items():
|
||||||
|
# ensure_safe_name
|
||||||
|
if re.search(r'[\\/]', name):
|
||||||
|
raise ValueError("Path separators not allowed in script names")
|
||||||
|
script_text = TEMPLATE.format(
|
||||||
|
ep.module_name, ep.attrs[0], '.'.join(ep.attrs),
|
||||||
|
spec, group, name)
|
||||||
|
# pylint: disable=E1101
|
||||||
|
args = cls._get_script_args(type_, name, header, script_text)
|
||||||
|
for res in args:
|
||||||
|
yield res
|
||||||
|
|
||||||
|
|
||||||
|
# pylint: disable=E1101
|
||||||
|
easy_install.ScriptWriter.get_args = get_args
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import shutil
|
||||||
|
import sys
|
||||||
|
dests = sys.argv[1:] or ['.']
|
||||||
|
filename = re.sub('\.pyc$', '.py', __file__)
|
||||||
|
|
||||||
|
for dst in dests:
|
||||||
|
shutil.copy(filename, dst)
|
||||||
|
manifest_path = os.path.join(dst, 'MANIFEST.in')
|
||||||
|
setup_path = os.path.join(dst, 'setup.py')
|
||||||
|
|
||||||
|
# Insert the include statement to MANIFEST.in if not present
|
||||||
|
with open(manifest_path, 'a+') as manifest:
|
||||||
|
manifest.seek(0)
|
||||||
|
manifest_content = manifest.read()
|
||||||
|
if 'include fastentrypoints.py' not in manifest_content:
|
||||||
|
manifest.write(('\n' if manifest_content else '') +
|
||||||
|
'include fastentrypoints.py')
|
||||||
|
|
||||||
|
# Insert the import statement to setup.py if not present
|
||||||
|
with open(setup_path, 'a+') as setup:
|
||||||
|
setup.seek(0)
|
||||||
|
setup_content = setup.read()
|
||||||
|
if 'import fastentrypoints' not in setup_content:
|
||||||
|
setup.seek(0)
|
||||||
|
setup.truncate()
|
||||||
|
setup.write('import fastentrypoints\n' + setup_content)
|
@ -15,8 +15,7 @@ import astor.code_gen
|
|||||||
|
|
||||||
import hy
|
import hy
|
||||||
|
|
||||||
from hy.lex import LexException, PrematureEndOfInput
|
from hy.lex import LexException, PrematureEndOfInput, mangle
|
||||||
from hy.lex.parser import mangle
|
|
||||||
from hy.compiler import HyTypeError
|
from hy.compiler import HyTypeError
|
||||||
from hy.importer import (hy_eval, import_buffer_to_module,
|
from hy.importer import (hy_eval, import_buffer_to_module,
|
||||||
import_file_to_ast, import_file_to_hst,
|
import_file_to_ast, import_file_to_hst,
|
||||||
|
@ -11,7 +11,7 @@ from hy.model_patterns import (FORM, SYM, KEYWORD, STR, sym, brackets, whole,
|
|||||||
from funcparserlib.parser import some, many, oneplus, maybe, NoParseError
|
from funcparserlib.parser import some, many, oneplus, maybe, NoParseError
|
||||||
from hy.errors import HyCompileError, HyTypeError
|
from hy.errors import HyCompileError, HyTypeError
|
||||||
|
|
||||||
from hy.lex.parser import mangle, unmangle
|
from hy.lex import mangle, unmangle
|
||||||
|
|
||||||
import hy.macros
|
import hy.macros
|
||||||
from hy._compat import (
|
from hy._compat import (
|
||||||
|
@ -19,8 +19,7 @@
|
|||||||
(import [collections :as cabc])
|
(import [collections :as cabc])
|
||||||
(import [collections.abc :as cabc]))
|
(import [collections.abc :as cabc]))
|
||||||
(import [hy.models [HySymbol HyKeyword]])
|
(import [hy.models [HySymbol HyKeyword]])
|
||||||
(import [hy.lex [LexException PrematureEndOfInput tokenize]])
|
(import [hy.lex [LexException PrematureEndOfInput tokenize mangle unmangle]])
|
||||||
(import [hy.lex.parser [mangle unmangle]])
|
|
||||||
(import [hy.compiler [HyASTCompiler]])
|
(import [hy.compiler [HyASTCompiler]])
|
||||||
(import [hy.importer [hy-eval :as eval]])
|
(import [hy.importer [hy-eval :as eval]])
|
||||||
|
|
||||||
|
@ -2,17 +2,19 @@
|
|||||||
# This file is part of Hy, which is free software licensed under the Expat
|
# This file is part of Hy, which is free software licensed under the Expat
|
||||||
# license. See the LICENSE.
|
# license. See the LICENSE.
|
||||||
|
|
||||||
from rply.errors import LexingError
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import re, unicodedata
|
||||||
|
from hy._compat import str_type, isidentifier, UCS4
|
||||||
from hy.lex.exceptions import LexException, PrematureEndOfInput # NOQA
|
from hy.lex.exceptions import LexException, PrematureEndOfInput # NOQA
|
||||||
from hy.lex.lexer import lexer
|
|
||||||
from hy.lex.parser import parser
|
|
||||||
|
|
||||||
|
|
||||||
def tokenize(buf):
|
def tokenize(buf):
|
||||||
"""
|
"""
|
||||||
Tokenize a Lisp file or string buffer into internal Hy objects.
|
Tokenize a Lisp file or string buffer into internal Hy objects.
|
||||||
"""
|
"""
|
||||||
|
from hy.lex.lexer import lexer
|
||||||
|
from hy.lex.parser import parser
|
||||||
|
from rply.errors import LexingError
|
||||||
try:
|
try:
|
||||||
return parser.parse(lexer.lex(buf))
|
return parser.parse(lexer.lex(buf))
|
||||||
except LexingError as e:
|
except LexingError as e:
|
||||||
@ -23,3 +25,80 @@ def tokenize(buf):
|
|||||||
if e.source is None:
|
if e.source is None:
|
||||||
e.source = buf
|
e.source = buf
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
mangle_delim = 'X'
|
||||||
|
|
||||||
|
|
||||||
|
def mangle(s):
|
||||||
|
"""Stringify the argument and convert it to a valid Python identifier
|
||||||
|
according to Hy's mangling rules."""
|
||||||
|
def unicode_char_to_hex(uchr):
|
||||||
|
# Covert a unicode char to hex string, without prefix
|
||||||
|
return uchr.encode('unicode-escape').decode('utf-8').lstrip('\\U').lstrip('\\u').lstrip('0')
|
||||||
|
|
||||||
|
assert s
|
||||||
|
|
||||||
|
s = str_type(s)
|
||||||
|
s = s.replace("-", "_")
|
||||||
|
s2 = s.lstrip('_')
|
||||||
|
leading_underscores = '_' * (len(s) - len(s2))
|
||||||
|
s = s2
|
||||||
|
|
||||||
|
if s.endswith("?"):
|
||||||
|
s = 'is_' + s[:-1]
|
||||||
|
if not isidentifier(leading_underscores + s):
|
||||||
|
# Replace illegal characters with their Unicode character
|
||||||
|
# names, or hexadecimal if they don't have one.
|
||||||
|
s = 'hyx_' + ''.join(
|
||||||
|
c
|
||||||
|
if c != mangle_delim and isidentifier('S' + c)
|
||||||
|
# We prepend the "S" because some characters aren't
|
||||||
|
# allowed at the start of an identifier.
|
||||||
|
else '{0}{1}{0}'.format(mangle_delim,
|
||||||
|
unicodedata.name(c, '').lower().replace('-', 'H').replace(' ', '_')
|
||||||
|
or 'U{}'.format(unicode_char_to_hex(c)))
|
||||||
|
for c in unicode_to_ucs4iter(s))
|
||||||
|
|
||||||
|
s = leading_underscores + s
|
||||||
|
assert isidentifier(s)
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
def unmangle(s):
|
||||||
|
"""Stringify the argument and try to convert it to a pretty unmangled
|
||||||
|
form. This may not round-trip, because different Hy symbol names can
|
||||||
|
mangle to the same Python identifier."""
|
||||||
|
|
||||||
|
s = str_type(s)
|
||||||
|
|
||||||
|
s2 = s.lstrip('_')
|
||||||
|
leading_underscores = len(s) - len(s2)
|
||||||
|
s = s2
|
||||||
|
|
||||||
|
if s.startswith('hyx_'):
|
||||||
|
s = re.sub('{0}(U)?([_a-z0-9H]+?){0}'.format(mangle_delim),
|
||||||
|
lambda mo:
|
||||||
|
chr(int(mo.group(2), base=16))
|
||||||
|
if mo.group(1)
|
||||||
|
else unicodedata.lookup(
|
||||||
|
mo.group(2).replace('_', ' ').replace('H', '-').upper()),
|
||||||
|
s[len('hyx_'):])
|
||||||
|
if s.startswith('is_'):
|
||||||
|
s = s[len("is_"):] + "?"
|
||||||
|
s = s.replace('_', '-')
|
||||||
|
|
||||||
|
return '-' * leading_underscores + s
|
||||||
|
|
||||||
|
|
||||||
|
def unicode_to_ucs4iter(ustr):
|
||||||
|
# Covert a unicode string to an iterable object,
|
||||||
|
# elements in the object are single USC-4 unicode characters
|
||||||
|
if UCS4:
|
||||||
|
return ustr
|
||||||
|
ucs4_list = list(ustr)
|
||||||
|
for i, u in enumerate(ucs4_list):
|
||||||
|
if 0xD7FF < ord(u) < 0xDC00:
|
||||||
|
ucs4_list[i] += ucs4_list[i + 1]
|
||||||
|
del ucs4_list[i + 1]
|
||||||
|
return ucs4_list
|
||||||
|
@ -10,7 +10,7 @@ import re, unicodedata
|
|||||||
|
|
||||||
from rply import ParserGenerator
|
from rply import ParserGenerator
|
||||||
|
|
||||||
from hy._compat import str_type, isidentifier, UCS4
|
from hy._compat import str_type
|
||||||
from hy.models import (HyBytes, HyComplex, HyDict, HyExpression, HyFloat,
|
from hy.models import (HyBytes, HyComplex, HyDict, HyExpression, HyFloat,
|
||||||
HyInteger, HyKeyword, HyList, HySet, HyString, HySymbol)
|
HyInteger, HyKeyword, HyList, HySet, HyString, HySymbol)
|
||||||
from .lexer import lexer
|
from .lexer import lexer
|
||||||
@ -19,80 +19,6 @@ from .exceptions import LexException, PrematureEndOfInput
|
|||||||
|
|
||||||
pg = ParserGenerator([rule.name for rule in lexer.rules] + ['$end'])
|
pg = ParserGenerator([rule.name for rule in lexer.rules] + ['$end'])
|
||||||
|
|
||||||
mangle_delim = 'X'
|
|
||||||
|
|
||||||
def unicode_to_ucs4iter(ustr):
|
|
||||||
# Covert a unicode string to an iterable object,
|
|
||||||
# elements in the object are single USC-4 unicode characters
|
|
||||||
if UCS4:
|
|
||||||
return ustr
|
|
||||||
ucs4_list = list(ustr)
|
|
||||||
for i, u in enumerate(ucs4_list):
|
|
||||||
if 0xD7FF < ord(u) < 0xDC00:
|
|
||||||
ucs4_list[i] += ucs4_list[i + 1]
|
|
||||||
del ucs4_list[i + 1]
|
|
||||||
return ucs4_list
|
|
||||||
|
|
||||||
def mangle(s):
|
|
||||||
"""Stringify the argument and convert it to a valid Python identifier
|
|
||||||
according to Hy's mangling rules."""
|
|
||||||
def unicode_char_to_hex(uchr):
|
|
||||||
# Covert a unicode char to hex string, without prefix
|
|
||||||
return uchr.encode('unicode-escape').decode('utf-8').lstrip('\\U').lstrip('\\u').lstrip('0')
|
|
||||||
|
|
||||||
assert s
|
|
||||||
|
|
||||||
s = str_type(s)
|
|
||||||
s = s.replace("-", "_")
|
|
||||||
s2 = s.lstrip('_')
|
|
||||||
leading_underscores = '_' * (len(s) - len(s2))
|
|
||||||
s = s2
|
|
||||||
|
|
||||||
if s.endswith("?"):
|
|
||||||
s = 'is_' + s[:-1]
|
|
||||||
if not isidentifier(leading_underscores + s):
|
|
||||||
# Replace illegal characters with their Unicode character
|
|
||||||
# names, or hexadecimal if they don't have one.
|
|
||||||
s = 'hyx_' + ''.join(
|
|
||||||
c
|
|
||||||
if c != mangle_delim and isidentifier('S' + c)
|
|
||||||
# We prepend the "S" because some characters aren't
|
|
||||||
# allowed at the start of an identifier.
|
|
||||||
else '{0}{1}{0}'.format(mangle_delim,
|
|
||||||
unicodedata.name(c, '').lower().replace('-', 'H').replace(' ', '_')
|
|
||||||
or 'U{}'.format(unicode_char_to_hex(c)))
|
|
||||||
for c in unicode_to_ucs4iter(s))
|
|
||||||
|
|
||||||
s = leading_underscores + s
|
|
||||||
assert isidentifier(s)
|
|
||||||
return s
|
|
||||||
|
|
||||||
|
|
||||||
def unmangle(s):
|
|
||||||
"""Stringify the argument and try to convert it to a pretty unmangled
|
|
||||||
form. This may not round-trip, because different Hy symbol names can
|
|
||||||
mangle to the same Python identifier."""
|
|
||||||
|
|
||||||
s = str_type(s)
|
|
||||||
|
|
||||||
s2 = s.lstrip('_')
|
|
||||||
leading_underscores = len(s) - len(s2)
|
|
||||||
s = s2
|
|
||||||
|
|
||||||
if s.startswith('hyx_'):
|
|
||||||
s = re.sub('{0}(U)?([_a-z0-9H]+?){0}'.format(mangle_delim),
|
|
||||||
lambda mo:
|
|
||||||
chr(int(mo.group(2), base=16))
|
|
||||||
if mo.group(1)
|
|
||||||
else unicodedata.lookup(
|
|
||||||
mo.group(2).replace('_', ' ').replace('H', '-').upper()),
|
|
||||||
s[len('hyx_'):])
|
|
||||||
if s.startswith('is_'):
|
|
||||||
s = s[len("is_"):] + "?"
|
|
||||||
s = s.replace('_', '-')
|
|
||||||
|
|
||||||
return '-' * leading_underscores + s
|
|
||||||
|
|
||||||
|
|
||||||
def set_boundaries(fun):
|
def set_boundaries(fun):
|
||||||
@wraps(fun)
|
@wraps(fun)
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
from hy._compat import PY3
|
from hy._compat import PY3
|
||||||
import hy.inspect
|
import hy.inspect
|
||||||
from hy.models import replace_hy_obj, HyExpression, HySymbol, wrap_value
|
from hy.models import replace_hy_obj, HyExpression, HySymbol, wrap_value
|
||||||
from hy.lex.parser import mangle
|
from hy.lex import mangle
|
||||||
from hy._compat import str_type
|
from hy._compat import str_type
|
||||||
|
|
||||||
from hy.errors import HyTypeError, HyMacroExpansionError
|
from hy.errors import HyTypeError, HyMacroExpansionError
|
||||||
|
1
setup.py
1
setup.py
@ -7,6 +7,7 @@ import sys, os
|
|||||||
|
|
||||||
from setuptools import find_packages, setup
|
from setuptools import find_packages, setup
|
||||||
from setuptools.command.install import install
|
from setuptools.command.install import install
|
||||||
|
import fastentrypoints # Monkey-patches setuptools.
|
||||||
|
|
||||||
from get_version import __version__
|
from get_version import __version__
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user