Skip to content

Commit e6ef803

Browse files
Kartik Rajkarthiknadig
andauthored
Merge release branch back into main (#15005)
* Revert "Add a locator for executables on $PATH on Windows. (#14981) This reverts commit 651a6b9. Co-authored-by: Karthik Nadig <[email protected]> * Version and changelog update (#14982) * Only activate discovery component when in experiment (#14985) * Update version and changelog (#14986) * Update version and changelog * Update package and package.lock json Co-authored-by: Karthik Nadig <[email protected]>
1 parent e3b4150 commit e6ef803

File tree

20 files changed

+355
-1122
lines changed

20 files changed

+355
-1122
lines changed

CHANGELOG.md

Lines changed: 123 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,128 @@
11
# Changelog
22

3-
## 2020.12.0-rc (10 December 2020)
3+
## 2020.12.2 (15 December 2020)
4+
5+
### Fixes
6+
7+
1. Only activate discovery component when in experiment.
8+
([#14977](https://github.com/Microsoft/vscode-python/issues/14977))
9+
10+
### Thanks
11+
12+
Thanks to the following projects which we fully rely on to provide some of
13+
our features:
14+
15+
- [debugpy](https://pypi.org/project/debugpy/)
16+
- [isort](https://pypi.org/project/isort/)
17+
- [jedi](https://pypi.org/project/jedi/)
18+
and [parso](https://pypi.org/project/parso/)
19+
- [Microsoft Python Language Server](https://github.com/microsoft/python-language-server)
20+
- [Pylance](https://github.com/microsoft/pylance-release)
21+
- [exuberant ctags](http://ctags.sourceforge.net/) (user-installed)
22+
- [rope](https://pypi.org/project/rope/) (user-installed)
23+
24+
Also thanks to the various projects we provide integrations with which help
25+
make this extension useful:
26+
27+
- Debugging support:
28+
[Django](https://pypi.org/project/Django/),
29+
[Flask](https://pypi.org/project/Flask/),
30+
[gevent](https://pypi.org/project/gevent/),
31+
[Jinja](https://pypi.org/project/Jinja/),
32+
[Pyramid](https://pypi.org/project/pyramid/),
33+
[PySpark](https://pypi.org/project/pyspark/),
34+
[Scrapy](https://pypi.org/project/Scrapy/),
35+
[Watson](https://pypi.org/project/Watson/)
36+
- Formatting:
37+
[autopep8](https://pypi.org/project/autopep8/),
38+
[black](https://pypi.org/project/black/),
39+
[yapf](https://pypi.org/project/yapf/)
40+
- Interpreter support:
41+
[conda](https://conda.io/),
42+
[direnv](https://direnv.net/),
43+
[pipenv](https://pypi.org/project/pipenv/),
44+
[pyenv](https://github.com/pyenv/pyenv),
45+
[venv](https://docs.python.org/3/library/venv.html#module-venv),
46+
[virtualenv](https://pypi.org/project/virtualenv/)
47+
- Linting:
48+
[bandit](https://pypi.org/project/bandit/),
49+
[flake8](https://pypi.org/project/flake8/),
50+
[mypy](https://pypi.org/project/mypy/),
51+
[prospector](https://pypi.org/project/prospector/),
52+
[pylint](https://pypi.org/project/pylint/),
53+
[pydocstyle](https://pypi.org/project/pydocstyle/),
54+
[pylama](https://pypi.org/project/pylama/)
55+
- Testing:
56+
[nose](https://pypi.org/project/nose/),
57+
[pytest](https://pypi.org/project/pytest/),
58+
[unittest](https://docs.python.org/3/library/unittest.html#module-unittest)
59+
60+
And finally thanks to the [Python](https://www.python.org/) development team and
61+
community for creating a fantastic programming language and community to be a
62+
part of!
63+
64+
## 2020.12.1 (15 December 2020)
65+
66+
### Fixes
67+
68+
1. Fix for extension loading issue in the latest release.
69+
([#14977](https://github.com/Microsoft/vscode-python/issues/14977))
70+
71+
### Thanks
72+
73+
Thanks to the following projects which we fully rely on to provide some of
74+
our features:
75+
76+
- [debugpy](https://pypi.org/project/debugpy/)
77+
- [isort](https://pypi.org/project/isort/)
78+
- [jedi](https://pypi.org/project/jedi/)
79+
and [parso](https://pypi.org/project/parso/)
80+
- [Microsoft Python Language Server](https://github.com/microsoft/python-language-server)
81+
- [Pylance](https://github.com/microsoft/pylance-release)
82+
- [exuberant ctags](http://ctags.sourceforge.net/) (user-installed)
83+
- [rope](https://pypi.org/project/rope/) (user-installed)
84+
85+
Also thanks to the various projects we provide integrations with which help
86+
make this extension useful:
87+
88+
- Debugging support:
89+
[Django](https://pypi.org/project/Django/),
90+
[Flask](https://pypi.org/project/Flask/),
91+
[gevent](https://pypi.org/project/gevent/),
92+
[Jinja](https://pypi.org/project/Jinja/),
93+
[Pyramid](https://pypi.org/project/pyramid/),
94+
[PySpark](https://pypi.org/project/pyspark/),
95+
[Scrapy](https://pypi.org/project/Scrapy/),
96+
[Watson](https://pypi.org/project/Watson/)
97+
- Formatting:
98+
[autopep8](https://pypi.org/project/autopep8/),
99+
[black](https://pypi.org/project/black/),
100+
[yapf](https://pypi.org/project/yapf/)
101+
- Interpreter support:
102+
[conda](https://conda.io/),
103+
[direnv](https://direnv.net/),
104+
[pipenv](https://pypi.org/project/pipenv/),
105+
[pyenv](https://github.com/pyenv/pyenv),
106+
[venv](https://docs.python.org/3/library/venv.html#module-venv),
107+
[virtualenv](https://pypi.org/project/virtualenv/)
108+
- Linting:
109+
[bandit](https://pypi.org/project/bandit/),
110+
[flake8](https://pypi.org/project/flake8/),
111+
[mypy](https://pypi.org/project/mypy/),
112+
[prospector](https://pypi.org/project/prospector/),
113+
[pylint](https://pypi.org/project/pylint/),
114+
[pydocstyle](https://pypi.org/project/pydocstyle/),
115+
[pylama](https://pypi.org/project/pylama/)
116+
- Testing:
117+
[nose](https://pypi.org/project/nose/),
118+
[pytest](https://pypi.org/project/pytest/),
119+
[unittest](https://docs.python.org/3/library/unittest.html#module-unittest)
120+
121+
And finally thanks to the [Python](https://www.python.org/) development team and
122+
community for creating a fantastic programming language and community to be a
123+
part of!
124+
125+
## 2020.12.0 (14 December 2020)
4126

5127
### Enhancements
6128

src/client/common/utils/exec.ts

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -44,45 +44,12 @@ function parseSearchPathEntries(envVarValue: string): string[] {
4444
* If the file does not exist or has any other problem when accessed
4545
* then `false` is returned. The caller is responsible to determine
4646
* whether or not the file exists.
47-
*
48-
* If it could not be determined if the file is executable (e.g. on
49-
* Windows) then `undefined` is returned. This allows the caller
50-
* to decide what to do.
5147
*/
5248
export async function isValidAndExecutable(filename: string): Promise<boolean | undefined> {
53-
// There are three options when it comes to checking if a file
54-
// is executable: `fs.stat()`, `fs.access()`, and
55-
// `child_process.exec()`. `stat()` requires non-trivial logic
56-
// to deal with user/group/everyone permissions. `exec()` requires
57-
// that we make an attempt to actually execute the file, which is
58-
// beyond the scope of this function (due to potential security
59-
// risks). That leaves `access()`, which is what we use.
6049
try {
61-
// We do not need to check if the file exists. `fs.access()`
62-
// takes care of that for us.
6350
await fsapi.promises.access(filename, fsapi.constants.X_OK);
6451
} catch (err) {
6552
return false;
6653
}
67-
if (getOSType() === OSType.Windows) {
68-
// On Windows a file is determined to be executable through
69-
// its ACLs. However, the FS-related functionality provided
70-
// by node does not check them (currently). This includes both
71-
// `fs.stat()` and `fs.access()` (which we used above). One
72-
// option is to use the "acl" NPM package (or something similar)
73-
// to make the relevant checks. However, we want to avoid
74-
// adding a dependency needlessly. Another option is to fall
75-
// back to checking the filename's suffix (e.g. ".exe"). The
76-
// problem there is that such a check is a bit *too* naive.
77-
// Finally, we could still go the `exec()` route. We'd
78-
// rather not given the concern identified above. Instead,
79-
// it is good enough to return `undefined` and let the
80-
// caller decide what to do about it. That is better
81-
// than returning `true` when we aren't sure.
82-
//
83-
// Note that we still call `fs.access()` on Windows first,
84-
// in case node makes it smarter later.
85-
return undefined;
86-
}
8754
return true;
8855
}

src/client/common/utils/text.ts

Lines changed: 0 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -111,138 +111,3 @@ export function parsePosition(raw: string | number): Position {
111111
}
112112
return new Position(line, col);
113113
}
114-
115-
/**
116-
* Return the indentation part of the given line.
117-
*/
118-
export function getIndent(line: string): string {
119-
const found = line.match(/^ */);
120-
return found![0];
121-
}
122-
123-
/**
124-
* Return the dedented lines in the given text.
125-
*
126-
* This is used to represent text concisely and readably, which is
127-
* particularly useful for declarative definitions (e.g. in tests).
128-
*
129-
* (inspired by Python's `textwrap.dedent()`)
130-
*/
131-
export function getDedentedLines(text: string): string[] {
132-
const linesep = text.includes('\r') ? '\r\n' : '\n';
133-
const lines = text.split(linesep);
134-
if (!lines) {
135-
return [text];
136-
}
137-
138-
if (lines[0] !== '') {
139-
throw Error('expected actual first line to be blank');
140-
}
141-
lines.shift();
142-
143-
if (lines[0] === '') {
144-
throw Error('expected "first" line to not be blank');
145-
}
146-
const leading = getIndent(lines[0]).length;
147-
148-
for (let i = 0; i < lines.length; i += 1) {
149-
const line = lines[i];
150-
if (getIndent(line).length < leading) {
151-
throw Error(`line ${i} has less indent than the "first" line`);
152-
}
153-
lines[i] = line.substring(leading);
154-
}
155-
156-
return lines;
157-
}
158-
159-
/**
160-
* Extract a tree based on the given text.
161-
*
162-
* The tree is derived from the indent level of each line. The caller
163-
* is responsible for applying any meaning to the text of each node
164-
* in the tree.
165-
*
166-
* Blank lines and comments (with a leading `#`) are ignored. Also,
167-
* the full text is automatically dedented until at least one line
168-
* has no indent (i.e. is treated as a root).
169-
*
170-
* @returns - the list of nodes in the tree (pairs of text & parent index)
171-
* (note that the parent index of roots is `-1`)
172-
*
173-
* Example:
174-
*
175-
* parseTree(`
176-
* # This comment and the following blank line are ignored.
177-
*
178-
* this is a root
179-
* the first branch
180-
* a sub-branch # This comment is ignored.
181-
* this is the first leaf node!
182-
* another leaf node...
183-
* middle
184-
*
185-
* the second main branch
186-
* # indents do not have to be consistent across the full text.
187-
* # ...and the indent of comments is not relevant.
188-
* node 1
189-
* node 2
190-
*
191-
* the last leaf node!
192-
*
193-
* another root
194-
* nothing to see here!
195-
*
196-
* # this comment is ignored
197-
* `.trim())
198-
*
199-
* would produce the following:
200-
*
201-
* [
202-
* ['this is a root', -1],
203-
* ['the first branch', 0],
204-
* ['a sub-branch', 1],
205-
* ['this is the first leaf node!', 2],
206-
* ['another leaf node...', 1],
207-
* ['middle', 1],
208-
* ['the second main branch', 0],
209-
* ['node 1', 6],
210-
* ['node 2', 6],
211-
* ['the last leaf node!', 0],
212-
* ['another root', -1],
213-
* ['nothing to see here!', 10],
214-
* ]
215-
*/
216-
export function parseTree(text: string): [string, number][] {
217-
const parsed: [string, number][] = [];
218-
const parents: [string, number][] = [];
219-
220-
const lines = getDedentedLines(text)
221-
.map((l) => l.split(' #')[0].split(' //')[0].trimEnd())
222-
.filter((l) => l.trim() !== '');
223-
lines.forEach((line) => {
224-
const indent = getIndent(line);
225-
const entry = line.trim();
226-
227-
let parentIndex: number;
228-
if (indent === '') {
229-
parentIndex = -1;
230-
parents.push([indent, parsed.length]);
231-
} else if (parsed.length === 0) {
232-
throw Error(`expected non-indented line, got ${line}`);
233-
} else {
234-
let parentIndent: string;
235-
[parentIndent, parentIndex] = parents[parents.length - 1];
236-
while (indent.length <= parentIndent.length) {
237-
parents.pop();
238-
[parentIndent, parentIndex] = parents[parents.length - 1];
239-
}
240-
if (parentIndent.length < indent.length) {
241-
parents.push([indent, parsed.length]);
242-
}
243-
}
244-
parsed.push([entry, parentIndex!]);
245-
});
246-
247-
return parsed;
248-
}

src/client/extensionActivation.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,15 +69,15 @@ import { ITestCodeNavigatorCommandHandler, ITestExplorerCommandHandler } from '.
6969
import { registerTypes as unitTestsRegisterTypes } from './testing/serviceRegistry';
7070

7171
// components
72-
import * as pythonEnvironments from './pythonEnvironments';
72+
// import * as pythonEnvironments from './pythonEnvironments';
7373

7474
import { ActivationResult, ExtensionState } from './components';
7575
import { Components } from './extensionInit';
7676

7777
export async function activateComponents(
7878
// `ext` is passed to any extra activation funcs.
7979
ext: ExtensionState,
80-
components: Components
80+
_components: Components
8181
): Promise<ActivationResult[]> {
8282
// Note that each activation returns a promise that resolves
8383
// when that activation completes. However, it might have started
@@ -89,7 +89,13 @@ export async function activateComponents(
8989
// activation resolves `ActivationResult`, which can safely wrap
9090
// the "inner" promise.
9191
const promises: Promise<ActivationResult>[] = [
92-
pythonEnvironments.activate(components.pythonEnvs),
92+
// tslint:disable-next-line:no-suspicious-comment
93+
// TODO: For now the extension should only interact with the component via the component adapter,
94+
// which takes care of putting the component behind the experiment flag. It already activates the
95+
// component among other things, hence the following is not needed.
96+
// pythonEnvironments.activate(components.pythonEnvs),
97+
// If we need to activate, we need to use the adapter:
98+
// https://github.com/microsoft/vscode-python/issues/14984
9399
// These will go away eventually.
94100
activateLegacy(ext)
95101
];

src/client/pythonEnvironments/base/envsCache.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,7 @@ export class PythonEnvsCache {
6565
if (this.byExecutable === undefined) {
6666
this.byExecutable = {};
6767
for (const env of this.envs) {
68-
const key = getEnvExecutable(env.executable.filename);
69-
this.byExecutable[key] = env;
68+
this.byExecutable[env.executable.filename] = env;
7069
}
7170
}
7271
return this.byExecutable[executable];

0 commit comments

Comments
 (0)