Skip to content

Commit

Permalink
Merge pull request #342 from takluyver/no-py2
Browse files Browse the repository at this point in the history
Re-drop Python 2 support in flit_core
  • Loading branch information
takluyver committed May 16, 2020
2 parents 9a9e641 + ee52c29 commit cfd71d8
Show file tree
Hide file tree
Showing 16 changed files with 115 additions and 163 deletions.
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ python:
- "3.6"
- "3.5"
- "3.4" # 3.4 & 2.7 only test flit_core - see tox.ini
- "2.7"

jobs:
include:
Expand Down
2 changes: 0 additions & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ environment:
TOX_APPVEYOR_X64: "1"
- TOXENV: "py35"
TOX_APPVEYOR_X64: "0"
- TOXENV: "py27"
TOX_APPVEYOR_X64: "1"

# The Python version here doesn't matter (except that the commands have the same),
# as Tox will set up an environment using the Python specified above.
Expand Down
2 changes: 1 addition & 1 deletion flit/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
def read_flit_config(path):
"""Read and check the `pyproject.toml` or `flit.ini` file with data about the package.
"""
res = _read_flit_config_core(str(path))
res = _read_flit_config_core(path)

if validate_config(res):
if os.environ.get('FLIT_ALLOW_INVALID'):
Expand Down
8 changes: 4 additions & 4 deletions flit/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def __init__(self, directory, ini_info, user=None, python=sys.executable,
if deps == 'none' and extras:
raise DependencyError()

self.module = common.Module(self.ini_info.module, str(directory))
self.module = common.Module(self.ini_info.module, directory)

if (hasattr(os, 'getuid') and (os.getuid() == 0) and
(not os.environ.get('FLIT_ROOT_INSTALL'))):
Expand Down Expand Up @@ -285,7 +285,7 @@ def install_directly(self):
os.makedirs(dirs['purelib'], exist_ok=True)
os.makedirs(dirs['scripts'], exist_ok=True)

dst = osp.join(dirs['purelib'], osp.basename(self.module.path))
dst = osp.join(dirs['purelib'], self.module.path.name)
if osp.lexists(dst):
if osp.isdir(dst) and not osp.islink(dst):
shutil.rmtree(dst)
Expand All @@ -303,12 +303,12 @@ def install_directly(self):
src = str(self.module.path)
if self.symlink:
log.info("Symlinking %s -> %s", src, dst)
os.symlink(osp.abspath(self.module.path), dst)
os.symlink(osp.abspath(src), dst)
self.installed_files.append(dst)
elif self.pth:
# .pth points to the the folder containing the module (which is
# added to sys.path)
pth_target = osp.dirname(osp.abspath(self.module.path))
pth_target = osp.dirname(osp.abspath(src))
pth_file = pathlib.Path(dst).with_suffix('.pth')
log.info("Adding .pth file %s for %s", pth_file, pth_target)
with pth_file.open("w") as f:
Expand Down
13 changes: 3 additions & 10 deletions flit/sdist.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,15 +140,10 @@ class SdistBuilder(SdistBuilderCore):
- Add a generated setup.py for compatibility with tools which don't yet know
about PEP 517.
"""
@classmethod
def from_ini_path(cls, ini_path: Path):
return super().from_ini_path(str(ini_path))

def select_files(self):
cfgdir_path = Path(self.cfgdir)
vcs_mod = identify_vcs(cfgdir_path)
vcs_mod = identify_vcs(self.cfgdir)
if vcs_mod is not None:
untracked_deleted = vcs_mod.list_untracked_deleted_files(cfgdir_path)
untracked_deleted = vcs_mod.list_untracked_deleted_files(self.cfgdir)
if any(include_path(p) and not self.excludes.match_file(p)
for p in untracked_deleted):
raise VCSError(
Expand All @@ -157,7 +152,7 @@ def select_files(self):
self.cfgdir)

files = [os.path.normpath(p)
for p in vcs_mod.list_tracked_files(cfgdir_path)]
for p in vcs_mod.list_tracked_files(self.cfgdir)]
files = sorted(filter(include_path, files))
log.info("Found %d files tracked in %s", len(files), vcs_mod.name)
else:
Expand Down Expand Up @@ -219,5 +214,3 @@ def make_setup_py(self):
extra='\n '.join(extra),
).encode('utf-8')

def build(self, target_dir, gen_setup_py=True):
return Path(super().build(str(target_dir), gen_setup_py=gen_setup_py))
10 changes: 2 additions & 8 deletions flit/wheel.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
import logging
from pathlib import Path

import flit_core.wheel as core_wheel

log = logging.getLogger(__name__)

def make_wheel_in(ini_path, wheel_directory):
info = core_wheel.make_wheel_in(str(ini_path), str(wheel_directory))
info.file = Path(info.file)
return info

return core_wheel.make_wheel_in(ini_path, wheel_directory)

class WheelBuilder(core_wheel.WheelBuilder):
@classmethod
def from_ini_path(cls, ini_path, target_fp):
return super().from_ini_path(str(ini_path), target_fp)
pass

23 changes: 12 additions & 11 deletions flit_core/flit_core/build_thyself.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@
import io
import os
import os.path as osp
from pathlib import Path
import tempfile

from .common import Metadata, Module, dist_info_name
from .wheel import WheelBuilder, _write_wheel_file, _replace
from .wheel import WheelBuilder, _write_wheel_file
from .sdist import SdistBuilder

from . import __version__
Expand All @@ -26,7 +27,7 @@
'requires_dist': [
'pytoml',
],
'requires_python': '>=2.7, !=3.0, !=3.1, !=3.2, != 3.3',
'requires_python': '>=3.4',
'classifiers': [
"License :: OSI Approved :: BSD License",
"Topic :: Software Development :: Libraries :: Python Modules",
Expand Down Expand Up @@ -58,21 +59,21 @@ def prepare_metadata_for_build_wheel(metadata_directory, config_settings=None):

def build_wheel(wheel_directory, config_settings=None, metadata_directory=None):
"""Builds a wheel, places it in wheel_directory"""
srcdir = os.getcwd()
module = Module('flit_core', srcdir)
cwd = Path.cwd()
module = Module('flit_core', cwd)

# We don't know the final filename until metadata is loaded, so write to
# a temporary_file, and rename it afterwards.
(fd, temp_path) = tempfile.mkstemp(suffix='.whl', dir=str(wheel_directory))
try:
with io.open(fd, 'w+b') as fp:
wb = WheelBuilder(
srcdir, module, metadata, entrypoints={}, target_fp=fp
cwd, module, metadata, entrypoints={}, target_fp=fp
)
wb.build()

wheel_path = osp.join(wheel_directory, wb.wheel_filename)
_replace(temp_path, str(wheel_path))
os.replace(temp_path, wheel_path)
except:
os.unlink(temp_path)
raise
Expand All @@ -81,14 +82,14 @@ def build_wheel(wheel_directory, config_settings=None, metadata_directory=None):

def build_sdist(sdist_directory, config_settings=None):
"""Builds an sdist, places it in sdist_directory"""
srcdir = os.getcwd()
module = Module('flit_core', srcdir)
cwd = Path.cwd()
module = Module('flit_core', cwd)
reqs_by_extra = {'.none': metadata.requires}

sb = SdistBuilder(
module, metadata, srcdir, reqs_by_extra, entrypoints={},
module, metadata, cwd, reqs_by_extra, entrypoints={},
extra_files=['pyproject.toml']
)
path = sb.build(sdist_directory)
return osp.basename(path)
path = sb.build(Path(sdist_directory))
return path.name

13 changes: 7 additions & 6 deletions flit_core/flit_core/buildapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import io
import os
import os.path as osp
from pathlib import Path

from .common import Module, make_metadata, write_entry_points, dist_info_name
from .config import read_flit_config
Expand All @@ -12,7 +13,7 @@
log = logging.getLogger(__name__)

# PEP 517 specifies that the CWD will always be the source tree
pyproj_toml = 'pyproject.toml'
pyproj_toml = Path('pyproject.toml')

def get_requires_for_build_wheel(config_settings=None):
"""Returns a list of requirements for building, as strings"""
Expand All @@ -25,7 +26,7 @@ def get_requires_for_build_wheel(config_settings=None):
def prepare_metadata_for_build_wheel(metadata_directory, config_settings=None):
"""Creates {metadata_directory}/foo-1.2.dist-info"""
ini_info = read_flit_config(pyproj_toml)
module = Module(ini_info.module, os.getcwd())
module = Module(ini_info.module, Path.cwd())
metadata = make_metadata(module, ini_info)

dist_info = osp.join(metadata_directory,
Expand All @@ -46,10 +47,10 @@ def prepare_metadata_for_build_wheel(metadata_directory, config_settings=None):

def build_wheel(wheel_directory, config_settings=None, metadata_directory=None):
"""Builds a wheel, places it in wheel_directory"""
info = make_wheel_in(pyproj_toml, wheel_directory)
return osp.basename(info.file)
info = make_wheel_in(pyproj_toml, Path(wheel_directory))
return info.file.name

def build_sdist(sdist_directory, config_settings=None):
"""Builds an sdist, places it in sdist_directory"""
path = SdistBuilder.from_ini_path(pyproj_toml).build(sdist_directory)
return osp.basename(path)
path = SdistBuilder.from_ini_path(pyproj_toml).build(Path(sdist_directory))
return path.name
70 changes: 30 additions & 40 deletions flit_core/flit_core/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
import logging
import os
import os.path as osp
from pathlib import Path
import re
import sys

log = logging.getLogger(__name__)

Expand All @@ -14,33 +14,33 @@
class Module(object):
"""This represents the module/package that we are going to distribute
"""
def __init__(self, name, directory='.'):
def __init__(self, name, directory=Path()):
self.name = name
self.directory = directory

# It must exist either as a .py file or a directory, but not both
pkg_dir = osp.join(directory, name)
py_file = osp.join(directory, name+'.py')
src_pkg_dir = osp.join(directory, 'src', name)
src_py_file = osp.join(directory, 'src', name+'.py')
pkg_dir = directory / name
py_file = directory / (name+'.py')
src_pkg_dir = directory / 'src' / name
src_py_file = directory / 'src' / (name+'.py')

existing = set()
if osp.isdir(pkg_dir):
if pkg_dir.is_dir():
self.path = pkg_dir
self.is_package = True
self.prefix = ''
existing.add(pkg_dir)
if osp.isfile(py_file):
if py_file.is_file():
self.path = py_file
self.is_package = False
self.prefix = ''
existing.add(py_file)
if osp.isdir(src_pkg_dir):
if src_pkg_dir.is_dir():
self.path = src_pkg_dir
self.is_package = True
self.prefix = 'src'
existing.add(src_pkg_dir)
if osp.isfile(src_py_file):
if src_py_file.is_file():
self.path = src_py_file
self.is_package = False
self.prefix = 'src'
Expand All @@ -49,20 +49,20 @@ def __init__(self, name, directory='.'):
if len(existing) > 1:
raise ValueError(
"Multiple files or folders could be module {}: {}"
.format(name, ", ".join(sorted(existing)))
.format(name, ", ".join([str(p) for p in sorted(existing)]))
)
elif not existing:
raise ValueError("No file/folder found for module {}".format(name))

@property
def source_dir(self):
"""Path of folder containing the module (src/ or project root)"""
return osp.dirname(self.path)
return self.path.parent

@property
def file(self):
if self.is_package:
return osp.join(self.path, '__init__.py')
return self.path / '__init__.py'
else:
return self.path

Expand All @@ -89,7 +89,7 @@ def _include(path):
dirs[:] = [d for d in sorted(dirs) if _include(d)]

else:
yield self.path
yield str(self.path)

class ProblemInModule(ValueError): pass
class NoDocstringError(ProblemInModule): pass
Expand Down Expand Up @@ -123,7 +123,7 @@ def get_docstring_and_version_via_ast(target):
extracted by parsing its AST.
"""
# read as bytes to enable custom encodings
with open(target.file, 'rb') as f:
with target.file.open('rb') as f:
node = ast.parse(f.read())
for child in node.body:
# Only use the version from the given module if it's a simple
Expand All @@ -140,31 +140,21 @@ def get_docstring_and_version_via_ast(target):
return ast.get_docstring(node), version


if sys.version_info[0] >= 3:
def get_docstring_and_version_via_import(target):
"""
Return a tuple like (docstring, version) for the given module,
extracted by importing the module and pulling __doc__ & __version__
from it.
"""
log.debug("Loading module %s", target.file)
from importlib.machinery import SourceFileLoader
sl = SourceFileLoader(target.name, target.file)
with _module_load_ctx():
m = sl.load_module()
docstring = m.__dict__.get('__doc__', None)
version = m.__dict__.get('__version__', None)
return docstring, version
else:
def get_docstring_and_version_via_import(target):
log.debug("Loading module %s", target.file)
import imp
mod_info = imp.find_module(target.name, [target.source_dir])
with _module_load_ctx():
m = imp.load_module(target.name, *mod_info)
docstring = m.__dict__.get('__doc__', None)
version = m.__dict__.get('__version__', None)
return docstring, version
def get_docstring_and_version_via_import(target):
"""
Return a tuple like (docstring, version) for the given module,
extracted by importing the module and pulling __doc__ & __version__
from it.
"""
log.debug("Loading module %s", target.file)
from importlib.machinery import SourceFileLoader
sl = SourceFileLoader(target.name, str(target.file))
with _module_load_ctx():
m = sl.load_module()
docstring = m.__dict__.get('__doc__', None)
version = m.__dict__.get('__version__', None)
return docstring, version


def get_info_from_module(target):
"""Load the module/package, get its docstring and __version__
Expand Down

0 comments on commit cfd71d8

Please sign in to comment.