Merge branch 'master' into develop

This commit is contained in:
ines 2017-04-07 12:00:26 +02:00
commit 7dd134718a
18 changed files with 242 additions and 45 deletions

View File

@ -22,9 +22,9 @@ install:
script: script:
- "pip install pytest" - "pip install pytest"
- if [[ "${VIA}" == "compile" ]]; then python -m pytest spacy; fi - if [[ "${VIA}" == "compile" ]]; then python -m pytest --tb=native spacy; fi
- if [[ "${VIA}" == "pypi" ]]; then python -m pytest `python -c "import os.path; import spacy; print(os.path.abspath(ospath.dirname(spacy.__file__)))"`; fi - if [[ "${VIA}" == "pypi" ]]; then python -m pytest --tb=native `python -c "import os.path; import spacy; print(os.path.abspath(ospath.dirname(spacy.__file__)))"`; fi
- if [[ "${VIA}" == "sdist" ]]; then python -m pytest `python -c "import os.path; import spacy; print(os.path.abspath(os.path.dirname(spacy.__file__)))"`; fi - if [[ "${VIA}" == "sdist" ]]; then python -m pytest --tb=native `python -c "import os.path; import spacy; print(os.path.abspath(os.path.dirname(spacy.__file__)))"`; fi
notifications: notifications:
slack: slack:

View File

@ -7,6 +7,7 @@ This is a list of everyone who has made significant contributions to spaCy, in a
* Andrew Poliakov, [@pavlin99th](https://github.com/pavlin99th) * Andrew Poliakov, [@pavlin99th](https://github.com/pavlin99th)
* Aniruddha Adhikary [@aniruddha-adhikary](https://github.com/aniruddha-adhikary) * Aniruddha Adhikary [@aniruddha-adhikary](https://github.com/aniruddha-adhikary)
* Bhargav Srinivasa, [@bhargavvader](https://github.com/bhargavvader) * Bhargav Srinivasa, [@bhargavvader](https://github.com/bhargavvader)
* Bruno P. Kinoshita, [@kinow](https://github.com/kinow)
* Chris DuBois, [@chrisdubois](https://github.com/chrisdubois) * Chris DuBois, [@chrisdubois](https://github.com/chrisdubois)
* Christoph Schwienheer, [@chssch](https://github.com/chssch) * Christoph Schwienheer, [@chssch](https://github.com/chssch)
* Dafne van Kuppevelt, [@dafnevk](https://github.com/dafnevk) * Dafne van Kuppevelt, [@dafnevk](https://github.com/dafnevk)
@ -14,6 +15,7 @@ This is a list of everyone who has made significant contributions to spaCy, in a
* Dmytro Sadovnychyi, [@sadovnychyi](https://github.com/sadovnychyi) * Dmytro Sadovnychyi, [@sadovnychyi](https://github.com/sadovnychyi)
* Eric Zhao, [@ericzhao28](https://github.com/ericzhao28) * Eric Zhao, [@ericzhao28](https://github.com/ericzhao28)
* Greg Baker, [@solresol](https://github.com/solresol) * Greg Baker, [@solresol](https://github.com/solresol)
* Grégory Howard, [@Gregory-Howard](https://github.com/Gregory-Howard)
* György Orosz, [@oroszgy](https://github.com/oroszgy) * György Orosz, [@oroszgy](https://github.com/oroszgy)
* Henning Peters, [@henningpeters](https://github.com/henningpeters) * Henning Peters, [@henningpeters](https://github.com/henningpeters)
* Iddo Berger, [@iddoberger](https://github.com/iddoberger) * Iddo Berger, [@iddoberger](https://github.com/iddoberger)
@ -21,6 +23,7 @@ This is a list of everyone who has made significant contributions to spaCy, in a
* J Nicolas Schrading, [@NSchrading](https://github.com/NSchrading) * J Nicolas Schrading, [@NSchrading](https://github.com/NSchrading)
* Janneke van der Zwaan, [@jvdzwaan](https://github.com/jvdzwaan) * Janneke van der Zwaan, [@jvdzwaan](https://github.com/jvdzwaan)
* Jordan Suchow, [@suchow](https://github.com/suchow) * Jordan Suchow, [@suchow](https://github.com/suchow)
* Josh Reeter, [@jreeter](https://github.com/jreeter)
* Juan Miguel Cejuela, [@juanmirocks](https://github.com/juanmirocks) * Juan Miguel Cejuela, [@juanmirocks](https://github.com/juanmirocks)
* Kendrick Tan, [@kendricktan](https://github.com/kendricktan) * Kendrick Tan, [@kendricktan](https://github.com/kendricktan)
* Kyle P. Johnson, [@kylepjohnson](https://github.com/kylepjohnson) * Kyle P. Johnson, [@kylepjohnson](https://github.com/kylepjohnson)
@ -30,6 +33,7 @@ This is a list of everyone who has made significant contributions to spaCy, in a
* Matthew Honnibal, [@honnibal](https://github.com/honnibal) * Matthew Honnibal, [@honnibal](https://github.com/honnibal)
* Maxim Samsonov, [@maxirmx](https://github.com/maxirmx) * Maxim Samsonov, [@maxirmx](https://github.com/maxirmx)
* Michael Wallin, [@wallinm1](https://github.com/wallinm1) * Michael Wallin, [@wallinm1](https://github.com/wallinm1)
* Miguel Almeida, [@mamoit](https://github.com/mamoit)
* Oleg Zd, [@olegzd](https://github.com/olegzd) * Oleg Zd, [@olegzd](https://github.com/olegzd)
* Pokey Rule, [@pokey](https://github.com/pokey) * Pokey Rule, [@pokey](https://github.com/pokey)
* Raphaël Bournhonesque, [@raphael0202](https://github.com/raphael0202) * Raphaël Bournhonesque, [@raphael0202](https://github.com/raphael0202)

View File

@ -46,7 +46,7 @@ def symlink(model_path, link_name, force):
# Add workaround for Python 2 on Windows (see issue #909) # Add workaround for Python 2 on Windows (see issue #909)
if util.is_python2() and util.is_windows(): if util.is_python2() and util.is_windows():
import subprocess import subprocess
command = ['mklink', '/d', link_path.as_posix(), model_path.as_posix()] command = ['mklink', '/d', link_path, model_path]
subprocess.call(command, shell=True) subprocess.call(command, shell=True)
else: else:
link_path.symlink_to(model_path) link_path.symlink_to(model_path)

View File

@ -213,15 +213,15 @@ for verb_data in [
{ORTH: "does", LEMMA: "do"}, {ORTH: "does", LEMMA: "do"},
{ORTH: "did", LEMMA: "do", TAG: "VBD"}, {ORTH: "did", LEMMA: "do", TAG: "VBD"},
{ORTH: "had", LEMMA: "have", TAG: "VBD"}, {ORTH: "had", LEMMA: "have", TAG: "VBD"},
{ORTH: "may"}, {ORTH: "may", TAG: "MD"},
{ORTH: "might"}, {ORTH: "might", TAG: "MD"},
{ORTH: "must"}, {ORTH: "must", TAG: "MD"},
{ORTH: "need"}, {ORTH: "need"},
{ORTH: "ought"}, {ORTH: "ought"},
{ORTH: "sha", LEMMA: "shall"}, {ORTH: "sha", LEMMA: "shall", TAG: "MD"},
{ORTH: "should"}, {ORTH: "should", TAG: "MD"},
{ORTH: "wo", LEMMA: "will"}, {ORTH: "wo", LEMMA: "will", TAG: "MD"},
{ORTH: "would"} {ORTH: "would", TAG: "MD"}
]: ]:
verb_data_tc = dict(verb_data) verb_data_tc = dict(verb_data)
verb_data_tc[ORTH] = verb_data_tc[ORTH].title() verb_data_tc[ORTH] = verb_data_tc[ORTH].title()

View File

@ -144,6 +144,7 @@ class BaseDefaults(object):
pipeline.append(nlp.tagger) pipeline.append(nlp.tagger)
if nlp.parser: if nlp.parser:
pipeline.append(nlp.parser) pipeline.append(nlp.parser)
pipeline.append(PseudoProjectivity.deprojectivize)
if nlp.entity: if nlp.entity:
pipeline.append(nlp.entity) pipeline.append(nlp.entity)
return pipeline return pipeline

View File

@ -161,6 +161,13 @@ def _convert_strings(token_specs, string_store):
return tokens return tokens
def merge_phrase(matcher, doc, i, matches):
'''Callback to merge a phrase on match'''
ent_id, label, start, end = matches[i]
span = doc[start : end]
span.merge(ent_type=label, ent_id=ent_id)
cdef class Matcher: cdef class Matcher:
'''Match sequences of tokens, based on pattern rules.''' '''Match sequences of tokens, based on pattern rules.'''
cdef Pool mem cdef Pool mem

View File

@ -5,13 +5,15 @@ from .. import language_data as base
from ..language_data import update_exc, strings_to_exc from ..language_data import update_exc, strings_to_exc
from .stop_words import STOP_WORDS from .stop_words import STOP_WORDS
from .tokenizer_exceptions import TOKENIZER_EXCEPTIONS, ORTH_ONLY
STOP_WORDS = set(STOP_WORDS) STOP_WORDS = set(STOP_WORDS)
TOKENIZER_EXCEPTIONS = strings_to_exc(base.EMOTICONS) TOKENIZER_EXCEPTIONS = dict(TOKENIZER_EXCEPTIONS)
update_exc(TOKENIZER_EXCEPTIONS, strings_to_exc(ORTH_ONLY))
update_exc(TOKENIZER_EXCEPTIONS, strings_to_exc(base.ABBREVIATIONS)) update_exc(TOKENIZER_EXCEPTIONS, strings_to_exc(base.ABBREVIATIONS))
update_exc(TOKENIZER_EXCEPTIONS, strings_to_exc(base.EMOTICONS))
__all__ = ["TOKENIZER_EXCEPTIONS", "STOP_WORDS"] __all__ = ["TOKENIZER_EXCEPTIONS", "STOP_WORDS"]

View File

@ -3,18 +3,19 @@ from __future__ import unicode_literals
STOP_WORDS = set(""" STOP_WORDS = set("""
à às acerca adeus agora ainda algmas algo algumas alguns ali além ambos ano à às acerca adeus agora ainda algo algumas alguns ali além ambas ambos ano
anos antes ao aos apenas apoio apontar após aquela aquelas aquele aqueles aqui anos antes ao aos apenas apoio apoia apontar após aquela aquelas aquele aqueles
aquilo area área as assim através atrás até aqui aquilo área as assim através atrás até
baixo bastante bem bom breve baixo bastante bem boa bom breve
cada caminho catorze cedo cento certamente certeza cima cinco coisa com como cada caminho catorze cedo cento certamente certeza cima cinco coisa com como
comprido conhecido conselho contra corrente custa comprido comprida conhecida conhecido conselho contra corrente custa
da daquela daquele dar das de debaixo demais dentro depois desde desligado da daquela daquele dar das de debaixo demais dentro depois desde desligada
dessa desse desta deste deve devem deverá dez dezanove dezasseis dezassete desligado dessa desse desta deste deve devem deverá dez dezanove dezasseis
dezoito dia diante direita diz dizem dizer do dois dos doze duas dão dúvida dezassete dezoito dia diante direita diz dizem dizer do dois dos doze duas
dão dúvida
é ela elas ele eles em embora enquanto entre então era és essa essas esse esses é ela elas ele eles em embora enquanto entre então era és essa essas esse esses
esta estado estar estará estas estava este estes esteve estive estivemos esta estado estar estará estas estava este estes esteve estive estivemos
@ -27,7 +28,7 @@ geral grande grandes grupo
hoje horas hoje horas
iniciar inicio ir irá isso ista iste isto iniciar inicio ir irá isso isto
lado ligado local logo longe lugar lado ligado local logo longe lugar
@ -35,32 +36,53 @@ maior maioria maiorias mais mal mas me meio menor menos meses mesmo meu meus
mil minha minhas momento muito muitos máximo mês mil minha minhas momento muito muitos máximo mês
na nada naquela naquele nas nem nenhuma nessa nesse nesta neste no noite nome na nada naquela naquele nas nem nenhuma nessa nesse nesta neste no noite nome
nos nossa nossas nosso nossos nova nove novo novos num numa nunca não nível s nos nossa nossas nosso nossos nova novas nove novo novos num numa nunca nuns
número não nível nós número números
obra obrigada obrigado oitava oitavo oito onde ontem onze os ou outra outras obra obrigada obrigado oitava oitavo oito onde ontem onze os ou outra outras
outro outros outro outros
para parece parte partir pegar pela pelas pelo pelos perto pessoas pode podem para parece parte partir pegar pela pelas pelo pelos perto pessoas pode podem
poder poderá podia ponto pontos por porque porquê posição possivelmente posso poder poderá podia ponto pontos por porque porquê posição possivelmente posso
possível pouca pouco povo primeira primeiro promeiro próprio próximo puderam possível pouca pouco povo primeira primeiro próprio próxima próximo puderam pôde
pôde põe põem põe põem
qual qualquer quando quanto quarta quarto quatro que quem quer quero questão qual qualquer quando quanto quarta quarto quatro que quem quer querem quero
quieto quinta quinto quinze quê relação questão quieta quieto quinta quinto quinze quê
relação
sabe saber se segunda segundo sei seis sem sempre ser seria sete seu seus sexta sabe saber se segunda segundo sei seis sem sempre ser seria sete seu seus sexta
sexto sim sistema sob sobre sois somente somos sou sua suas são sétima sétimo sexto sim sistema sob sobre sois somente somos sou sua suas são sétima sétimo
tal talvez também tanto tarde te tem temos tempo tendes tenho tens tentar tal talvez também tanta tanto tarde te tem temos tempo tendes tenho tens tentar
tentaram tente tentei ter terceira terceiro teu teus teve tipo tive tivemos tentaram tente tentei ter terceira terceiro teu teus teve tipo tive tivemos
tiveram tiveste tivestes toda todas todo todos trabalhar trabalho treze três tu tiveram tiveste tivestes toda todas todo todos trabalhar trabalho treze três tu
tua tuas tudo tão têm tua tuas tudo tão têm
último um uma umas uns usa usar último um uma umas uns usa usar
vai vais valor veja vem vens ver verdade verdadeiro vez vezes viagem vindo vai vais valor veja vem vens ver verdade verdadeira verdadeiro vez vezes viagem
vinte você vocês vos vossa vossas vosso vossos vários vão vêm vós vinda vindo vinte você vocês vos vossa vossas vosso vossos vários vão vêm vós
zero zero
""".split()) """.split())
# Number words
NUM_WORDS = set("""
zero um dois três quatro cinco seis sete oito nove dez onze doze treze catorze
quinze dezasseis dezassete dezoito dezanove vinte trinta quarenta cinquenta
sessenta setenta oitenta noventa cem mil milhão bilião trilião quadrilião
""".split())
# Ordinal words
ORDINAL_WORDS = set("""
primeiro segundo terceiro quarto quinto sexto sétimo oitavo nono décimo
vigésimo trigésimo quadragésimo quinquagésimo sexagésimo septuagésimo
octogésimo nonagésimo centésimo ducentésimo trecentésimo quadringentésimo
quingentésimo sexcentésimo septingentésimo octingentésimo nongentésimo
milésimo milionésimo bilionésimo
""".split())

View File

@ -0,0 +1,111 @@
# coding: utf8
from __future__ import unicode_literals
from ..symbols import *
from ..language_data import PRON_LEMMA
TOKENIZER_EXCEPTIONS = {}
# Contractions
CONTRACTIONS = {}
personal_pronoun = (
"ele", "ela", "eles", "elas"
)
demonstrative_pronouns = (
"este", "esta", "estes", "estas", "isto", "esse", "essa", "esses", "essas",
"isso", "aquele", "aquela", "aqueles", "aquelas", "aquilo"
)
undefined_pronouns = (
"outro", "outra", "outros", "outras"
)
adverbs = (
"aqui", "", "ali", "além"
)
for word in personal_pronoun + demonstrative_pronouns + \
undefined_pronouns + adverbs:
CONTRACTIONS["d" + word] = [
{ORTH: "d", NORM: "de"},
{ORTH: word}
]
for word in personal_pronoun + demonstrative_pronouns + \
undefined_pronouns:
CONTRACTIONS["n" + word] = [
{ORTH: "n", NORM: "em"},
{ORTH: word}
]
# Not so linear contractions "a"+something
CONTRACTIONS.update({
# This one cannot be split into 2
# "à": [
# {ORTH: "à", NORM: "a"},
# {ORTH: "", NORM: "a"}
# ],
"às": [
{ORTH: "à", NORM: "a"},
{ORTH: "s", NORM: "as"}
],
"ao": [
{ORTH: "a"},
{ORTH: "o"}
],
"aos": [
{ORTH: "a"},
{ORTH: "os"}
],
"àquele": [
{ORTH: "à", NORM: "a"},
{ORTH: "quele", NORM: "aquele"}
],
"àquela": [
{ORTH: "à", NORM: "a"},
{ORTH: "quela", NORM: "aquela"}
],
"àqueles": [
{ORTH: "à", NORM: "a"},
{ORTH: "queles", NORM: "aqueles"}
],
"àquelas": [
{ORTH: "à", NORM: "a"},
{ORTH: "quelas", NORM: "aquelas"}
],
"àquilo": [
{ORTH: "à", NORM: "a"},
{ORTH: "quilo", NORM: "aquilo"}
],
"aonde": [
{ORTH: "a"},
{ORTH: "onde"}
],
})
TOKENIZER_EXCEPTIONS.update(CONTRACTIONS)
# Abbreviations with only one ORTH token
ORTH_ONLY = [
"Adm.",
"Dr.",
"e.g.",
"E.g.",
"E.G.",
"Gen.",
"Gov.",
"i.e.",
"I.e.",
"I.E.",
"Jr.",
"Ltd.",
"p.m.",
"Ph.D.",
"Rep.",
"Rev.",
"Sen.",
"Sr.",
"Sra.",
"vs.",
]

View File

@ -427,8 +427,6 @@ cdef class ArcEager(TransitionSystem):
def finalize_doc(self, doc): def finalize_doc(self, doc):
doc.is_parsed = True doc.is_parsed = True
if doc.vocab.lang == 'de':
PseudoProjectivity.deprojectivize(doc)
cdef int set_valid(self, int* output, const StateC* st) nogil: cdef int set_valid(self, int* output, const StateC* st) nogil:
cdef bint[N_MOVES] is_valid cdef bint[N_MOVES] is_valid

View File

@ -257,6 +257,7 @@ cdef class Parser:
cdef int parseC(self, TokenC* tokens, int length, int nr_feat) nogil: cdef int parseC(self, TokenC* tokens, int length, int nr_feat) nogil:
state = new StateC(tokens, length) state = new StateC(tokens, length)
# NB: This can change self.moves.n_moves! # NB: This can change self.moves.n_moves!
# I think this causes memory errors if called by .pipe()
self.moves.initialize_state(state) self.moves.initialize_state(state)
nr_class = self.moves.n_moves nr_class = self.moves.n_moves

View File

@ -0,0 +1,17 @@
from ... import load as load_spacy
from ...attrs import LEMMA
from ...matcher import merge_phrase
import pytest
@pytest.mark.models
def test_issue758():
'''Test parser transition bug after label added.'''
nlp = load_spacy('en')
nlp.matcher.add('splash', 'my_entity', {},
[[{LEMMA: 'splash'}, {LEMMA: 'on'}]],
on_match=merge_phrase)
doc = nlp('splash On', parse=False)

View File

@ -19,6 +19,15 @@ def test_spans_merge_tokens(en_tokenizer):
assert doc[0].text == 'Los Angeles' assert doc[0].text == 'Los Angeles'
assert doc[0].head.text == 'start' assert doc[0].head.text == 'start'
doc = get_doc(tokens.vocab, [t.text for t in tokens], heads=heads)
assert len(doc) == 4
assert doc[0].head.text == 'Angeles'
assert doc[1].head.text == 'start'
doc.merge(0, len('Los Angeles'), tag='NNP', lemma='Los Angeles', label='GPE')
assert len(doc) == 3
assert doc[0].text == 'Los Angeles'
assert doc[0].head.text == 'start'
assert doc[0].ent_type_ == 'GPE'
def test_spans_merge_heads(en_tokenizer): def test_spans_merge_heads(en_tokenizer):
text = "I found a pilates class near work." text = "I found a pilates class near work."

View File

@ -667,6 +667,16 @@ cdef class Doc:
attributes[TAG] = self.vocab.strings[tag] attributes[TAG] = self.vocab.strings[tag]
attributes[LEMMA] = self.vocab.strings[lemma] attributes[LEMMA] = self.vocab.strings[lemma]
attributes[ENT_TYPE] = self.vocab.strings[ent_type] attributes[ENT_TYPE] = self.vocab.strings[ent_type]
elif not args:
# TODO: This code makes little sense overall. We're still
# ignoring most of the attributes?
if "label" in attributes and 'ent_type' not in attributes:
if type(attributes["label"]) == int:
attributes[ENT_TYPE] = attributes["label"]
else:
attributes[ENT_TYPE] = self.vocab.strings[attributes["label"]]
if 'ent_type' in attributes:
attributes[ENT_TYPE] = attributes['ent_type']
elif args: elif args:
raise ValueError( raise ValueError(
"Doc.merge received %d non-keyword arguments. " "Doc.merge received %d non-keyword arguments. "
@ -686,6 +696,9 @@ cdef class Doc:
tag = self.vocab.strings[attributes.get(TAG, span.root.tag)] tag = self.vocab.strings[attributes.get(TAG, span.root.tag)]
lemma = self.vocab.strings[attributes.get(LEMMA, span.root.lemma)] lemma = self.vocab.strings[attributes.get(LEMMA, span.root.lemma)]
ent_type = self.vocab.strings[attributes.get(ENT_TYPE, span.root.ent_type)] ent_type = self.vocab.strings[attributes.get(ENT_TYPE, span.root.ent_type)]
ent_id = attributes.get('ent_id', span.root.ent_id)
if isinstance(ent_id, basestring):
ent_id = self.vocab.strings[ent_id]
# Get LexemeC for newly merged token # Get LexemeC for newly merged token
new_orth = ''.join([t.text_with_ws for t in span]) new_orth = ''.join([t.text_with_ws for t in span])
@ -706,6 +719,7 @@ cdef class Doc:
else: else:
token.ent_iob = 3 token.ent_iob = 3
token.ent_type = self.vocab.strings[ent_type] token.ent_type = self.vocab.strings[ent_type]
token.ent_id = ent_id
# Begin by setting all the head indices to absolute token positions # Begin by setting all the head indices to absolute token positions
# This is easier to work with for now than the offsets # This is easier to work with for now than the offsets
# Before thinking of something simpler, beware the case where a dependency # Before thinking of something simpler, beware the case where a dependency

View File

@ -506,21 +506,15 @@ cdef class Token:
return self.c.ent_id return self.c.ent_id
def __set__(self, hash_t key): def __set__(self, hash_t key):
# TODO self.c.ent_id = key
raise NotImplementedError(
"Can't yet set ent_id from Token. Vote for this feature on the issue "
"tracker: http://github.com/spacy-io/spaCy")
property ent_id_: property ent_id_:
'''A (string) entity ID. Usually assigned by patterns in the Matcher.''' '''A (string) entity ID. Usually assigned by patterns in the Matcher.'''
def __get__(self): def __get__(self):
return self.vocab.strings[self.c.ent_id] return self.vocab.strings[self.c.ent_id]
def __set__(self, hash_t key): def __set__(self, name):
# TODO self.c.ent_id = self.vocab.strings[name]
raise NotImplementedError(
"Can't yet set ent_id_ from Token. Vote for this feature on the issue "
"tracker: http://github.com/spacy-io/spaCy")
property whitespace_: property whitespace_:
def __get__(self): def __get__(self):

View File

@ -7,7 +7,6 @@ import re
import os.path import os.path
import pathlib import pathlib
import sys import sys
import textwrap import textwrap

View File

@ -151,6 +151,11 @@
"url": "https://github.com/golastmile/rasa_nlu", "url": "https://github.com/golastmile/rasa_nlu",
"author": "LASTMILE", "author": "LASTMILE",
"description": "High level APIs for building your own language parser using existing NLP and ML libraries." "description": "High level APIs for building your own language parser using existing NLP and ML libraries."
},
"spacyr": {
"url": "https://github.com/kbenoit/spacyr",
"author": "Kenneth Benoit",
"description": "An R wrapper for spaCy."
} }
}, },
"visualizations": { "visualizations": {

View File

@ -33,7 +33,6 @@ p
| import the language's #[code Language] class instead, for example | import the language's #[code Language] class instead, for example
| #[code from spacy.fr import French]. | #[code from spacy.fr import French].
+h(3, "symlink-privilege") Symbolic link privilege not held +h(3, "symlink-privilege") Symbolic link privilege not held
+code(false, "text"). +code(false, "text").
@ -51,6 +50,20 @@ p
| or use a #[code virtualenv] to install spaCy in a user directory, instead | or use a #[code virtualenv] to install spaCy in a user directory, instead
| of doing a system-wide installation. | of doing a system-wide installation.
+h(3, "no-cache-dir") No such option: --no-cache-dir
+code(false, "text").
no such option: --no-cache-dir
p
| The #[code download] command uses pip to install the models and sets the
| #[code --no-cache-dir] flag to prevent it from requiring too much memory.
| #[+a("https://pip.pypa.io/en/stable/reference/pip_install/#caching") This setting]
| requires pip v6.0 or newer.
+infobox("Solution")
| Run #[code pip install -U pip] to upgrade to the latest version of pip.
| To see which version you have installed, run #[code pip --version].
+h(3, "import-error") Import error +h(3, "import-error") Import error