Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

general packaging improvements #17

Merged
merged 2 commits into from
May 25, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
fixes
  • Loading branch information
gaborbernat committed May 25, 2019
commit b41d942e368c8b9607d261dc906831bb4224e904
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,5 @@ typed-src/

pip-wheel-metadata
.mypy_cache

src/retype/version.py
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
requires = [
"setuptools >= 40.0.4",
"wheel >= 0.29.0",
"pypandoc",
"setuptools-scm >= 2, < 4",
]
build-backend = 'setuptools.build_meta'

Expand Down
62 changes: 56 additions & 6 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,8 +1,57 @@
[metadata]
name = retype
version = 1
description = re-apply types from .pyi stub files to your codebase
long_description = file: README.md
long_description_content_type = text/markdown
keywords = mypy typing typehints type hints pep484 pyi stubs
author = Łukasz Langa
author_email = lukasz@langa.pl
url = https://github.com/ambv/retype
project_urls =
Source=https://github.com/ambv/retype
Tracker=https://github.com/ambv/retype/issues
platforms = any

license = MIT
license_file = LICENSE
classifiers =
Development Status :: 3 - Alpha
Environment :: Console
Intended Audience :: Developers
License :: OSI Approved :: MIT License
Operating System :: OS Independent
Programming Language :: Python
Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7
Topic :: Software Development :: Libraries :: Python Modules
Topic :: Software Development :: Quality Assurance

[options]
packages = find:
python_requires = >=3.6

zip_safe = False
install_requires =
click
typed-ast
pathspec >= 0.5.9, <1

[options.extras_require]
testing =
pytest >= 3.0.0, <5
pytest-cov >= 2.5.1, <3

[options.packages.find]
where = src

[options.entry_points]
console_scripts =
retype=retype.__main__:main

[flake8]
ignore =
# using the B9 variant
E501,
# need to put some backlashes to force YAPF into submission
E502,
W503,
E225,
Expand All @@ -22,7 +71,8 @@ skip_covered = True
show_missing = True

[coverage:paths]
source = .
.tox/*/*/site-packages
.tox/*/*/*/site-packages
*/s
source =
src
.tox/*/*/site-packages
.tox/*/*/*/site-packages
*/s
91 changes: 16 additions & 75 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,80 +1,21 @@
# Copyright (C) 2017 Łukasz Langa

import ast
import os
import re
import sys
"""Handle the package management of the module"""
import textwrap

from setuptools import setup

try:
from pathlib import Path
except ImportError:
pass # will fail assert below.

assert sys.version_info >= (3, 6, 0), "retype requires Python 3.6+"


current_dir = os.path.abspath(os.path.dirname(__file__))
readme_md = os.path.join(current_dir, "README.md")
try:
import pypandoc

long_description = pypandoc.convert_file(readme_md, "rst")
except (IOError, ImportError):
print()
print(
"\x1b[31m\x1b[1mwarning:\x1b[0m\x1b[31m pandoc not found, "
"long description will be ugly (PyPI does not support .md)."
"\x1b[0m"
)
print()
with open(readme_md, encoding="utf8") as ld_file:
long_description = ld_file.read()


_version_re = re.compile(r"__version__\s+=\s+(?P<version>.*)")

version_in_file = os.path.join(current_dir, "retype.py")
with open(version_in_file, "r", encoding="utf8") as f:
match = _version_re.search(f.read())
if match is None:
raise RuntimeError("could not find __version__ in {}".format(version_in_file))
version = match.group("version")
version = str(ast.literal_eval(version))


setup(
name="retype",
version=version,
description="Re-apply types from .pyi stub files to your codebase.",
long_description=long_description,
long_description_content_type="text/x-rst",
keywords="mypy typing typehints type hints pep484 pyi stubs",
author="Łukasz Langa",
author_email="lukasz@langa.pl",
url="https://github.com/ambv/retype",
license="MIT",
py_modules=["retype", "retype_hgext"],
data_files=[
(
str(Path("lib/mypy/typeshed/third_party/3.6")),
("types/retype.pyi", "types/retype_hgext.pyi"),
)
],
zip_safe=False,
install_requires=["click", "typed-ast", "pathspec >= 0.5.9, <1"],
test_suite="tests.test_retype",
classifiers=[
"Development Status :: 3 - Alpha",
"Environment :: Console",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3.6",
"Topic :: Software Development :: Libraries :: Python Modules",
"Topic :: Software Development :: Quality Assurance",
],
entry_points={"console_scripts": ["retype=retype:main"]},
package_dir={"": "src"},
use_scm_version={
"write_to": "src/retype/version.py",
"write_to_template": textwrap.dedent(
'''
"""contains version information"""
from __future__ import unicode_literals

from typing import Text

__version__ = "{version}" # type: Text
'''
).lstrip(),
},
)
81 changes: 2 additions & 79 deletions retype.py → src/retype/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,81 +19,7 @@
from pathspec import PathSpec
from typed_ast import ast3

__version__ = "19.5.0"

Directory = partial(
click.Path,
exists=True,
file_okay=False,
dir_okay=True,
readable=True,
writable=False,
)


Config = threading.local()


@click.command()
@click.option(
"-p",
"--pyi-dir",
type=Directory(),
default="types",
help="Where to find .pyi stubs.",
show_default=True,
)
@click.option(
"-t",
"--target-dir",
type=Directory(exists=False, writable=True),
default="typed-src",
help="Where to write annotated sources.",
show_default=True,
)
@click.option(
"-i",
"--incremental",
is_flag=True,
help="Allow for missing type annotations in both stubs and the source.",
)
@click.option("-q", "--quiet", is_flag=True, help="Don't emit warnings, just errors.")
@click.option(
"-a", "--replace-any", is_flag=True, help="Allow replacing Any annotations."
)
@click.option(
"--hg", is_flag=True, help="Post-process files to preserve implicit byte literals."
)
@click.option("--traceback", is_flag=True, help="Show a Python traceback on error.")
@click.argument("src", nargs=-1, type=Directory(file_okay=True))
@click.version_option(version=__version__)
def main(src, pyi_dir, target_dir, incremental, quiet, replace_any, hg, traceback):
"""Re-apply type annotations from .pyi stubs to your codebase."""
Config.incremental = incremental
Config.replace_any = replace_any
returncode = 0
for src_entry in src:
for file, error, exc_type, tb in retype_path(
Path(src_entry),
pyi_dir=Path(pyi_dir),
targets=Path(target_dir),
src_explicitly_given=True,
quiet=quiet,
hg=hg,
):
print(f"error: {file}: {error}", file=sys.stderr)
if traceback:
print("Traceback (most recent call last):", file=sys.stderr)
for line in tb:
print(line, file=sys.stderr, end="")
print(f"{exc_type.__name__}: {error}", file=sys.stderr)
returncode += 1
if not src and not quiet:
print("warning: no sources given", file=sys.stderr)

# According to http://tldp.org/LDP/abs/html/index.html starting with 126
# we have special returncodes.
sys.exit(min(returncode, 125))
from .version import __version__


def retype_path(
Expand Down Expand Up @@ -182,7 +108,7 @@ def lib2to3_unparse(node, *, hg=False):
"""Given a lib2to3 node, return its string representation."""
code = str(node)
if hg:
from retype_hgext import apply_job_security
from src.retype import apply_job_security

code = apply_job_security(code)
return code
Expand Down Expand Up @@ -1508,6 +1434,3 @@ def walk_not_git_ignored(path, keep, extra_ignore):
""",
re.MULTILINE | re.VERBOSE,
)

if __name__ == "__main__":
main()
82 changes: 82 additions & 0 deletions src/retype/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import sys
from functools import partial

import click
from click import Path
from . import retype_path

from .version import __version__

Directory = partial(
click.Path,
exists=True,
file_okay=False,
dir_okay=True,
readable=True,
writable=False,
)


@click.command()
@click.option(
"-p",
"--pyi-dir",
type=Directory(),
default="types",
help="Where to find .pyi stubs.",
show_default=True,
)
@click.option(
"-t",
"--target-dir",
type=Directory(exists=False, writable=True),
default="typed-src",
help="Where to write annotated sources.",
show_default=True,
)
@click.option(
"-i",
"--incremental",
is_flag=True,
help="Allow for missing type annotations in both stubs and the source.",
)
@click.option("-q", "--quiet", is_flag=True, help="Don't emit warnings, just errors.")
@click.option(
"-a", "--replace-any", is_flag=True, help="Allow replacing Any annotations."
)
@click.option(
"--hg", is_flag=True, help="Post-process files to preserve implicit byte literals."
)
@click.option("--traceback", is_flag=True, help="Show a Python traceback on error.")
@click.argument("src", nargs=-1, type=Directory(file_okay=True))
@click.version_option(version=__version__)
def main(src, pyi_dir, target_dir, incremental, quiet, replace_any, hg, traceback):
"""Re-apply type annotations from .pyi stubs to your codebase."""

returncode = 0
for src_entry in src:
for file, error, exc_type, tb in retype_path(
Path(src_entry),
pyi_dir=Path(pyi_dir),
targets=Path(target_dir),
src_explicitly_given=True,
quiet=quiet,
hg=hg,
):
print(f"error: {file}: {error}", file=sys.stderr)
if traceback:
print("Traceback (most recent call last):", file=sys.stderr)
for line in tb:
print(line, file=sys.stderr, end="")
print(f"{exc_type.__name__}: {error}", file=sys.stderr)
returncode += 1
if not src and not quiet:
print("warning: no sources given", file=sys.stderr)

# According to http://tldp.org/LDP/abs/html/index.html starting with 126
# we have special returncodes.
sys.exit(min(returncode, 125))


if __name__ == "__main__":
main()
6 changes: 6 additions & 0 deletions src/retype/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from typing import NamedTuple


class Config(NamedTuple):
incremental: True
replace_any: True
File renamed without changes.
18 changes: 18 additions & 0 deletions tests/test_entry_points.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import subprocess
import sys
from pathlib import Path


def test_has_module_access():
subprocess.check_call([sys.executable, "-m", "retype", "--help"])


def test_has_script_call():
subprocess.check_call([Path(sys.executable).parent / "retype", "--help"])


def test_directly_invoke_able():
import retype

cmd = [sys.executable, str(Path(retype.__file__).parent / "__init__.py"), "--help"]
subprocess.check_call(cmd)
Loading