spaCy/spacy/cli/link.py

81 lines
2.8 KiB
Python
Raw Normal View History

# coding: utf8
from __future__ import unicode_literals
import pip
2017-03-18 14:59:21 +03:00
from pathlib import Path
2017-03-19 03:39:36 +03:00
import importlib
from .. import util
def link(origin, link_name, force=False):
if is_package(origin):
2017-03-18 14:59:21 +03:00
link_package(origin, link_name, force)
else:
symlink(origin, link_name, force)
2017-03-19 03:39:36 +03:00
def link_package(package_name, link_name, force=False):
# Here we're importing the module just to find it. This is worryingly
# indirect, but it's otherwise very difficult to find the package.
# Python's installation and import rules are very complicated.
pkg = importlib.import_module(package_name)
package_path = Path(pkg.__file__).parent.parent
meta = get_meta(package_path, package_name)
model_name = package_name + '-' + meta['version']
model_path = package_path / package_name / model_name
2017-03-17 23:35:51 +03:00
symlink(model_path, link_name, force)
def symlink(model_path, link_name, force):
model_path = Path(model_path)
2017-03-18 18:30:15 +03:00
if not Path(model_path).exists():
2017-03-16 19:08:58 +03:00
util.sys_exit(
"The data should be located in {p}".format(p=model_path),
title="Can't locate model data")
2017-03-18 20:57:31 +03:00
link_path = util.get_data_path() / link_name
2017-03-18 20:57:31 +03:00
if link_path.exists() and not force:
util.sys_exit(
"To overwrite an existing link, use the --force flag.",
title="Link {l} already exists".format(l=link_name))
elif link_path.exists():
link_path.unlink()
2017-03-18 14:59:21 +03:00
# Add workaround for Python 2 on Windows (see issue #909)
if util.is_python2() and util.is_windows():
2017-03-25 13:36:38 +03:00
import subprocess
command = ['mklink', '/d', unicode(link_path), unicode(model_path)]
try:
subprocess.call(command, shell=True)
except:
# This is quite dirty, but just making sure other Windows-specific
# errors are caught so users at least see a proper error message.
util.sys_exit(
"Creating a symlink in spacy/data failed. You can still import "
"the model as a Python package and call its load() method, or "
"create the symlink manually:",
"{a} --> {b}".format(a=unicode(model_path), b=unicode(link_path)),
title="Error: Couldn't link model to '{l}'".format(l=link_name))
2017-03-25 13:36:38 +03:00
else:
link_path.symlink_to(model_path)
2017-03-16 19:08:58 +03:00
util.print_msg(
2017-03-18 20:57:31 +03:00
"{a} --> {b}".format(a=model_path.as_posix(), b=link_path.as_posix()),
2017-03-16 19:08:58 +03:00
"You can now load the model via spacy.load('{l}').".format(l=link_name),
title="Linking successful")
def get_meta(package_path, package):
meta = util.parse_package_meta(package_path, package)
return meta
def is_package(origin):
packages = pip.get_installed_distributions()
for package in packages:
if package.project_name.replace('-', '_') == origin:
return True
return False