Skip to content

Commit 8e27b56

Browse files
committed
Deprecated develop option and rename to editable
1 parent 727907d commit 8e27b56

12 files changed

Lines changed: 261 additions & 64 deletions

File tree

poetry/core/factory.py

Lines changed: 140 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
from typing import Any
77
from typing import Dict
8+
from typing import Generator
89
from typing import List
910
from typing import Optional
1011
from typing import Union
@@ -27,6 +28,11 @@ class Factory(object):
2728
Factory class to create various elements needed by Poetry.
2829
"""
2930

31+
DEPRECATED_CONSTRAINT_KEY_CURRENT_KEY_MAP = {
32+
"allows_prereleases": "allow-prereleases",
33+
"develop": "editable",
34+
}
35+
3036
def create_poetry(
3137
self, cwd=None, with_dev=True
3238
): # type: (Optional[Path]. bool) -> Poetry
@@ -182,49 +188,40 @@ def create_dependency(
182188
constraint = "*"
183189

184190
if isinstance(constraint, dict):
185-
optional = constraint.get("optional", False)
186-
python_versions = constraint.get("python")
187-
platform = constraint.get("platform")
188-
markers = constraint.get("markers")
189-
if "allows-prereleases" in constraint:
190-
message = (
191-
'The "{}" dependency specifies '
192-
'the "allows-prereleases" property, which is deprecated. '
193-
'Use "allow-prereleases" instead.'.format(name)
194-
)
195-
warn(message, DeprecationWarning)
196-
logger.warning(message)
197-
198-
allows_prereleases = constraint.get(
199-
"allow-prereleases", constraint.get("allows-prereleases", False)
191+
constraint_without_deprecated_keys = cls.as_constraint_with_deprecated_keys_renamed_to_current_keys(
192+
dependency_name=name, constraint=constraint,
200193
)
194+
optional = constraint_without_deprecated_keys.get("optional", False)
195+
python_versions = constraint_without_deprecated_keys.get("python")
196+
platform = constraint_without_deprecated_keys.get("platform")
197+
markers = constraint_without_deprecated_keys.get("markers")
201198

202-
if "git" in constraint:
199+
if "git" in constraint_without_deprecated_keys:
203200
# VCS dependency
204201
dependency = VCSDependency(
205202
name,
206203
"git",
207-
constraint["git"],
208-
branch=constraint.get("branch", None),
209-
tag=constraint.get("tag", None),
210-
rev=constraint.get("rev", None),
204+
constraint_without_deprecated_keys["git"],
205+
branch=constraint_without_deprecated_keys.get("branch", None),
206+
tag=constraint_without_deprecated_keys.get("tag", None),
207+
rev=constraint_without_deprecated_keys.get("rev", None),
211208
category=category,
212209
optional=optional,
213-
develop=constraint.get("develop", False),
214-
extras=constraint.get("extras", []),
210+
editable=constraint_without_deprecated_keys.get("editable", False),
211+
extras=constraint_without_deprecated_keys.get("extras", []),
215212
)
216-
elif "file" in constraint:
217-
file_path = Path(constraint["file"])
213+
elif "file" in constraint_without_deprecated_keys:
214+
file_path = Path(constraint_without_deprecated_keys["file"])
218215

219216
dependency = FileDependency(
220217
name,
221218
file_path,
222219
category=category,
223220
base=root_dir,
224-
extras=constraint.get("extras", []),
221+
extras=constraint_without_deprecated_keys.get("extras", []),
225222
)
226-
elif "path" in constraint:
227-
path = Path(constraint["path"])
223+
elif "path" in constraint_without_deprecated_keys:
224+
path = Path(constraint_without_deprecated_keys["path"])
228225

229226
if root_dir:
230227
is_file = root_dir.joinpath(path).is_file()
@@ -238,7 +235,7 @@ def create_dependency(
238235
category=category,
239236
optional=optional,
240237
base=root_dir,
241-
extras=constraint.get("extras", []),
238+
extras=constraint_without_deprecated_keys.get("extras", []),
242239
)
243240
else:
244241
dependency = DirectoryDependency(
@@ -247,27 +244,31 @@ def create_dependency(
247244
category=category,
248245
optional=optional,
249246
base=root_dir,
250-
develop=constraint.get("develop", False),
251-
extras=constraint.get("extras", []),
247+
editable=constraint_without_deprecated_keys.get(
248+
"editable", False
249+
),
250+
extras=constraint_without_deprecated_keys.get("extras", []),
252251
)
253-
elif "url" in constraint:
252+
elif "url" in constraint_without_deprecated_keys:
254253
dependency = URLDependency(
255254
name,
256-
constraint["url"],
255+
constraint_without_deprecated_keys["url"],
257256
category=category,
258257
optional=optional,
259-
extras=constraint.get("extras", []),
258+
extras=constraint_without_deprecated_keys.get("extras", []),
260259
)
261260
else:
262-
version = constraint["version"]
261+
version = constraint_without_deprecated_keys["version"]
263262

264263
dependency = Dependency(
265264
name,
266265
version,
267266
optional=optional,
268267
category=category,
269-
allows_prereleases=allows_prereleases,
270-
extras=constraint.get("extras", []),
268+
allows_prereleases=constraint_without_deprecated_keys.get(
269+
"allow_prereleases", False
270+
),
271+
extras=constraint_without_deprecated_keys.get("extras", []),
271272
)
272273

273274
if not markers:
@@ -296,7 +297,7 @@ def create_dependency(
296297
if not marker.is_any():
297298
dependency.marker = marker
298299

299-
dependency.source_name = constraint.get("source")
300+
dependency.source_name = constraint_without_deprecated_keys.get("source")
300301
else:
301302
dependency = Dependency(name, constraint, category=category)
302303

@@ -329,12 +330,23 @@ def validate(
329330
if not isinstance(constraint, dict):
330331
continue
331332

332-
if "allows-prereleases" in constraint:
333-
result["warnings"].append(
334-
'The "{}" dependency specifies '
335-
'the "allows-prereleases" property, which is deprecated. '
336-
'Use "allow-prereleases" instead.'.format(name)
337-
)
333+
for deprecated_key in cls.deprecated_keys():
334+
if deprecated_key in constraint:
335+
if cls.constraint_has_deprecated_key_current_key_conflict(
336+
constraint, deprecated_key
337+
):
338+
result["errors"].append(
339+
cls.deprecated_constraint_key_current_key_conflict_error_message(
340+
dependency_name=name,
341+
deprecated_key=deprecated_key,
342+
)
343+
)
344+
else:
345+
result["warnings"].append(
346+
cls.constraint_key_deprecation_message(
347+
dependency_name=name, key=deprecated_key
348+
)
349+
)
338350

339351
# Checking for scripts with extras
340352
if "scripts" in config:
@@ -371,3 +383,88 @@ def locate(cls, cwd): # type: (Path) -> Path
371383
cwd
372384
)
373385
)
386+
387+
@classmethod
388+
def deprecated_keys(cls): # type: () -> Generator[str, None, None]
389+
for key in cls.DEPRECATED_CONSTRAINT_KEY_CURRENT_KEY_MAP:
390+
yield key
391+
392+
@classmethod
393+
def as_constraint_with_deprecated_keys_renamed_to_current_keys(
394+
cls, dependency_name, constraint
395+
): # type: (str, Dict[str, Any]) -> Dict[str, Any]
396+
constraint_with_renamed_keys = {}
397+
for key, value in constraint.items():
398+
if cls.is_deprecated_constraint_key(key):
399+
cls.raise_on_deprecated_constraint_key_current_key_conflict(
400+
dependency_name, constraint, key
401+
)
402+
cls.warn_constraint_key_is_deprecated(dependency_name, key)
403+
current_key = cls.DEPRECATED_CONSTRAINT_KEY_CURRENT_KEY_MAP[key]
404+
constraint_with_renamed_keys[current_key] = value
405+
else:
406+
constraint_with_renamed_keys[key] = value
407+
return constraint_with_renamed_keys
408+
409+
@classmethod
410+
def raise_on_deprecated_constraint_key_current_key_conflict(
411+
cls, dependency_name, constraint, deprecated_key
412+
): # type: (str, Dict[str, Any], str) -> None
413+
"""Raise `RuntimeError` when both a deprecated key and it's current, updated counterpart (key) are contained in constraint."""
414+
if cls.constraint_has_deprecated_key_current_key_conflict(
415+
constraint, deprecated_key
416+
):
417+
raise RuntimeError(
418+
cls.deprecated_constraint_key_current_key_conflict_error_message(
419+
dependency_name, deprecated_key,
420+
)
421+
)
422+
423+
@classmethod
424+
def constraint_has_deprecated_key_current_key_conflict(
425+
cls, constraint, deprecated_key
426+
): # type: (Dict[str, Any], str) -> bool
427+
current_key = cls.DEPRECATED_CONSTRAINT_KEY_CURRENT_KEY_MAP[deprecated_key]
428+
return current_key in constraint
429+
430+
@classmethod
431+
def deprecated_constraint_key_current_key_conflict_error_message(
432+
cls, dependency_name, deprecated_key
433+
): # type: (str, str) -> str
434+
current_key = cls.DEPRECATED_CONSTRAINT_KEY_CURRENT_KEY_MAP[deprecated_key]
435+
return (
436+
'The "{dependency_name}" dependency specifies '
437+
'both the "{current_key}" property and the deprecated "{deprecated_key}" property. '
438+
'Please remove "{deprecated_key}" and resolve value conflicts!'.format(
439+
dependency_name=dependency_name,
440+
current_key=current_key,
441+
deprecated_key=deprecated_key,
442+
)
443+
)
444+
445+
@classmethod
446+
def is_deprecated_constraint_key(cls, key): # type: (str) -> bool
447+
return key in cls.DEPRECATED_CONSTRAINT_KEY_CURRENT_KEY_MAP
448+
449+
@classmethod
450+
def warn_constraint_key_is_deprecated(
451+
cls, dependency_name, key
452+
): # type: (str, str) -> None
453+
message = cls.constraint_key_deprecation_message(dependency_name, key)
454+
warn(message, DeprecationWarning)
455+
logging.warning(message)
456+
457+
@classmethod
458+
def constraint_key_deprecation_message(
459+
cls, dependency_name, key
460+
): # type: (str, str) -> str
461+
current_key = cls.DEPRECATED_CONSTRAINT_KEY_CURRENT_KEY_MAP[key]
462+
return (
463+
'The "{dependency_name}" dependency specifies '
464+
'the "{deprecated_key}" property, which is deprecated. '
465+
'Use "{current_key}" instead.'.format(
466+
dependency_name=dependency_name,
467+
deprecated_key=key,
468+
current_key=current_key,
469+
)
470+
)

poetry/core/json/schemas/poetry-schema.json

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -359,9 +359,14 @@
359359
"type": "string"
360360
}
361361
},
362+
"editable": {
363+
"type": "boolean",
364+
"description": "Whether to install the dependency in editable mode."
365+
},
362366
"develop": {
363367
"type": "boolean",
364-
"description": "Whether to install the dependency in development mode."
368+
"description": "Whether to install the dependency in editable mode.",
369+
"deprecated": true
365370
}
366371
}
367372
},
@@ -435,9 +440,14 @@
435440
"type": "string"
436441
}
437442
},
443+
"editable": {
444+
"type": "boolean",
445+
"description": "Whether to install the dependency in editable mode."
446+
},
438447
"develop": {
439448
"type": "boolean",
440-
"description": "Whether to install the dependency in development mode."
449+
"description": "Whether to install the dependency in editable mode.",
450+
"deprecated": true
441451
}
442452
}
443453
},

poetry/core/packages/directory_dependency.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def __init__(
1616
category="main", # type: str
1717
optional=False, # type: bool
1818
base=None, # type: Path
19-
develop=False, # type: bool
19+
editable=False, # type: bool
2020
extras=None, # type: Union[List[str], Set[str]]
2121
):
2222
self._path = path
@@ -29,7 +29,7 @@ def __init__(
2929
except FileNotFoundError:
3030
raise ValueError("Directory {} does not exist".format(self._path))
3131

32-
self._develop = develop
32+
self._editable = editable
3333
self._supports_poetry = False
3434

3535
if not self._full_path.exists():
@@ -75,8 +75,8 @@ def base(self):
7575
return self._base
7676

7777
@property
78-
def develop(self):
79-
return self._develop
78+
def editable(self):
79+
return self._editable
8080

8181
def supports_poetry(self):
8282
return self._supports_poetry
@@ -91,7 +91,7 @@ def with_constraint(self, constraint):
9191
base=self.base,
9292
optional=self.is_optional(),
9393
category=self.category,
94-
develop=self._develop,
94+
editable=self._editable,
9595
extras=self._extras,
9696
)
9797

poetry/core/packages/package.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ def __init__(
9696

9797
self.root_dir = None
9898

99-
self.develop = True
99+
self.editable = True
100100

101101
@property
102102
def name(self):
@@ -319,7 +319,7 @@ def to_dependency(self):
319319
category=self.category,
320320
optional=self.optional,
321321
base=self.root_dir,
322-
develop=self.develop,
322+
editable=self.editable,
323323
extras=self.features,
324324
)
325325
elif self.source_type == "file":
@@ -348,7 +348,7 @@ def to_dependency(self):
348348
resolved_rev=self.source_resolved_reference,
349349
category=self.category,
350350
optional=self.optional,
351-
develop=self.develop,
351+
editable=self.editable,
352352
extras=self.features,
353353
)
354354
else:
@@ -405,7 +405,7 @@ def clone(self): # type: () -> "Package"
405405
clone.marker = self.marker
406406
clone.extras = self.extras
407407
clone.root_dir = self.root_dir
408-
clone.develop = self.develop
408+
clone.editable = self.editable
409409

410410
for dep in self.requires:
411411
clone.requires.append(dep)

0 commit comments

Comments
 (0)