Skip to content
This repository was archived by the owner on Nov 10, 2023. It is now read-only.

Commit a8e25cb

Browse files
bigfootjonlisroach
andauthored
Get Buck working for 3.10 (#2696) (#2697)
Cherry-picked from 1ae1e6c Summary: Pull Request resolved: #2696 On 3.10 some `collections` classes have been moved to `collections.abc` and it causes Buck 1 to crash. This diff fixes those instances. Really pex should be upgraded, but I made an attempt and it was very difficult due to our custom changes to pex. Reviewed By: bigfootjon fbshipit-source-id: 15a7bb96e664d5169b12de09e9157571782c861f Co-authored-by: Lisa Roach <[email protected]>
1 parent e9e9ef3 commit a8e25cb

File tree

11 files changed

+276
-217
lines changed

11 files changed

+276
-217
lines changed

scripts/slice_trace.py

-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616

1717
import argparse
1818
import codecs
19-
import collections
20-
import json
2119
import math
2220
import os
2321

third-party/py/pathlib/test_pathlib.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import collections
21
import io
32
import os
43
import errno
@@ -19,8 +18,10 @@
1918
raise ImportError("unittest2 is required for tests on pre-2.7")
2019

2120
try:
21+
import collections.abc as collections_abc
2222
from test import support
2323
except ImportError:
24+
import collections as collections_abc # Fallback for PY3.2.
2425
from test import test_support as support
2526
TESTFN = support.TESTFN
2627

@@ -1395,7 +1396,7 @@ def _check(glob, expected):
13951396
P = self.cls
13961397
p = P(BASE)
13971398
it = p.glob("fileA")
1398-
self.assertIsInstance(it, collections.Iterator)
1399+
self.assertIsInstance(it, collections_abc.Iterator)
13991400
_check(it, ["fileA"])
14001401
_check(p.glob("fileB"), [])
14011402
_check(p.glob("dir*/file*"), ["dirB/fileB", "dirC/fileC"])
@@ -1420,7 +1421,7 @@ def _check(glob, expected):
14201421
P = self.cls
14211422
p = P(BASE)
14221423
it = p.rglob("fileA")
1423-
self.assertIsInstance(it, collections.Iterator)
1424+
self.assertIsInstance(it, collections_abc.Iterator)
14241425
# XXX cannot test because of symlink loops in the test setup
14251426
#_check(it, ["fileA"])
14261427
#_check(p.rglob("fileB"), ["dirB/fileB"])

third-party/py/pex/README.facebook

+2
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,5 @@ Local modifications:
1313
- Back-ported Python 3.6 compatibility commit c5ab73fd4d8e816e21a89d48c8d0c8095ef5a49c
1414
- Back-ported namespaced packages fix, commit 7d2dc7f500aa7ae227c3ddca4b278b807d353a5e
1515
- Fixed Python 3 issue with writing bytes to a text file (`with open(path, 'wb') as fp:` on line 68 in `compiler.py`)
16+
- Imported from collections.abc instead of collections to support Python 3.10
17+
- Back-ported removal of MarkerEvaluation from pieces of commit ba5633b3c7b9317b87130a2ea671d8c008a673d6 and a718819d2849196e902808301c9a95724510c5c1

third-party/py/pex/pex/base.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33

44
from __future__ import absolute_import
55

6-
from collections import Iterable
6+
try:
7+
from collections.abc import Iterable
8+
except ImportError: # For PY3.2
9+
from collections import Iterable
710

811
from pkg_resources import Requirement
912

third-party/py/pex/pex/link.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,17 @@
55

66
import os
77
import posixpath
8-
from collections import Iterable
98

109
from .compatibility import string as compatible_string
1110
from .compatibility import PY3
1211
from .util import Memoizer
1312

13+
14+
try:
15+
from collections.abc import Iterable
16+
except ImportError: # For PY3.2
17+
from collections import Iterable
18+
1419
if PY3:
1520
import urllib.parse as urlparse
1621
else:

third-party/py/pex/pex/orderedset.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,14 @@
88
# modifications
99
#
1010

11-
import collections
1211

12+
try:
13+
import collections.abc as collections_abc
14+
except ImportError: # For PY3.2
15+
import collections as collections_abc
1316

14-
class OrderedSet(collections.MutableSet):
17+
18+
class OrderedSet(collections_abc.MutableSet):
1519
KEY, PREV, NEXT = range(3)
1620

1721
def __init__(self, iterable=None):

third-party/py/pywatchman/pywatchman/pybser.py

+9-5
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
# no unicode literals
3333

3434
import binascii
35-
import collections
3635
import ctypes
3736
import struct
3837
import sys
@@ -41,6 +40,11 @@
4140
compat,
4241
)
4342

43+
try:
44+
import collections.abc as collections_abc
45+
except ImportError:
46+
import collections as collections_abc # Fallback for PY3.2.
47+
4448
BSER_ARRAY = b'\x00'
4549
BSER_OBJECT = b'\x01'
4650
BSER_BYTESTRING = b'\x02'
@@ -177,8 +181,8 @@ def append_recursive(self, val):
177181
self.ensure_size(needed)
178182
struct.pack_into(b'=cd', self.buf, self.wpos, BSER_REAL, val)
179183
self.wpos += needed
180-
elif isinstance(val, collections.Mapping) and \
181-
isinstance(val, collections.Sized):
184+
elif isinstance(val, collections_abc.Mapping) and \
185+
isinstance(val, collections_abc.Sized):
182186
val_len = len(val)
183187
size = _int_size(val_len)
184188
needed = 2 + size
@@ -205,8 +209,8 @@ def append_recursive(self, val):
205209
for k, v in iteritems:
206210
self.append_string(k)
207211
self.append_recursive(v)
208-
elif isinstance(val, collections.Iterable) and \
209-
isinstance(val, collections.Sized):
212+
elif isinstance(val, collections_abc.Iterable) and \
213+
isinstance(val, collections_abc.Sized):
210214
val_len = len(val)
211215
size = _int_size(val_len)
212216
needed = 2 + size

third-party/py/pywatchman/tests/tests.py

-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
# no unicode literals
77

88
import binascii
9-
import collections
109
import inspect
1110
import unittest
1211
import os

third-party/py/setuptools/pkg_resources/__init__.py

+21-194
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import functools
3030
import pkgutil
3131
import token
32-
import symbol
3332
import operator
3433
import platform
3534
import collections
@@ -1402,202 +1401,30 @@ def to_filename(name):
14021401
return name.replace('-','_')
14031402

14041403

1405-
class MarkerEvaluation(object):
1406-
values = {
1407-
'os_name': lambda: os.name,
1408-
'sys_platform': lambda: sys.platform,
1409-
'python_full_version': platform.python_version,
1410-
'python_version': lambda: platform.python_version()[:3],
1411-
'platform_version': platform.version,
1412-
'platform_machine': platform.machine,
1413-
'platform_python_implementation': platform.python_implementation,
1414-
'python_implementation': platform.python_implementation,
1415-
}
1416-
1417-
@classmethod
1418-
def is_invalid_marker(cls, text):
1419-
"""
1420-
Validate text as a PEP 426 environment marker; return an exception
1421-
if invalid or False otherwise.
1422-
"""
1423-
try:
1424-
cls.evaluate_marker(text)
1425-
except SyntaxError as e:
1426-
return cls.normalize_exception(e)
1427-
return False
1428-
1429-
@staticmethod
1430-
def normalize_exception(exc):
1431-
"""
1432-
Given a SyntaxError from a marker evaluation, normalize the error
1433-
message:
1434-
- Remove indications of filename and line number.
1435-
- Replace platform-specific error messages with standard error
1436-
messages.
1437-
"""
1438-
subs = {
1439-
'unexpected EOF while parsing': 'invalid syntax',
1440-
'parenthesis is never closed': 'invalid syntax',
1441-
}
1442-
exc.filename = None
1443-
exc.lineno = None
1444-
exc.msg = subs.get(exc.msg, exc.msg)
1445-
return exc
1446-
1447-
@classmethod
1448-
def and_test(cls, nodelist):
1449-
# MUST NOT short-circuit evaluation, or invalid syntax can be skipped!
1450-
items = [
1451-
cls.interpret(nodelist[i])
1452-
for i in range(1, len(nodelist), 2)
1453-
]
1454-
return functools.reduce(operator.and_, items)
1455-
1456-
@classmethod
1457-
def test(cls, nodelist):
1458-
# MUST NOT short-circuit evaluation, or invalid syntax can be skipped!
1459-
items = [
1460-
cls.interpret(nodelist[i])
1461-
for i in range(1, len(nodelist), 2)
1462-
]
1463-
return functools.reduce(operator.or_, items)
1464-
1465-
@classmethod
1466-
def atom(cls, nodelist):
1467-
t = nodelist[1][0]
1468-
if t == token.LPAR:
1469-
if nodelist[2][0] == token.RPAR:
1470-
raise SyntaxError("Empty parentheses")
1471-
return cls.interpret(nodelist[2])
1472-
msg = "Language feature not supported in environment markers"
1473-
raise SyntaxError(msg)
1474-
1475-
@classmethod
1476-
def comparison(cls, nodelist):
1477-
if len(nodelist) > 4:
1478-
msg = "Chained comparison not allowed in environment markers"
1479-
raise SyntaxError(msg)
1480-
comp = nodelist[2][1]
1481-
cop = comp[1]
1482-
if comp[0] == token.NAME:
1483-
if len(nodelist[2]) == 3:
1484-
if cop == 'not':
1485-
cop = 'not in'
1486-
else:
1487-
cop = 'is not'
1488-
try:
1489-
cop = cls.get_op(cop)
1490-
except KeyError:
1491-
msg = repr(cop) + " operator not allowed in environment markers"
1492-
raise SyntaxError(msg)
1493-
return cop(cls.evaluate(nodelist[1]), cls.evaluate(nodelist[3]))
1494-
1495-
@classmethod
1496-
def get_op(cls, op):
1497-
ops = {
1498-
symbol.test: cls.test,
1499-
symbol.and_test: cls.and_test,
1500-
symbol.atom: cls.atom,
1501-
symbol.comparison: cls.comparison,
1502-
'not in': lambda x, y: x not in y,
1503-
'in': lambda x, y: x in y,
1504-
'==': operator.eq,
1505-
'!=': operator.ne,
1506-
'<': operator.lt,
1507-
'>': operator.gt,
1508-
'<=': operator.le,
1509-
'>=': operator.ge,
1510-
}
1511-
if hasattr(symbol, 'or_test'):
1512-
ops[symbol.or_test] = cls.test
1513-
return ops[op]
1514-
1515-
@classmethod
1516-
def evaluate_marker(cls, text, extra=None):
1517-
"""
1518-
Evaluate a PEP 426 environment marker on CPython 2.4+.
1519-
Return a boolean indicating the marker result in this environment.
1520-
Raise SyntaxError if marker is invalid.
1521-
1522-
This implementation uses the 'parser' module, which is not implemented
1523-
on
1524-
Jython and has been superseded by the 'ast' module in Python 2.6 and
1525-
later.
1526-
"""
1527-
return cls.interpret(parser.expr(text).totuple(1)[1])
1528-
1529-
@staticmethod
1530-
def _translate_metadata2(env):
1531-
"""
1532-
Markerlib implements Metadata 1.2 (PEP 345) environment markers.
1533-
Translate the variables to Metadata 2.0 (PEP 426).
1534-
"""
1535-
return dict(
1536-
(key.replace('.', '_'), value)
1537-
for key, value in env
1538-
)
1539-
1540-
@classmethod
1541-
def _markerlib_evaluate(cls, text):
1542-
"""
1543-
Evaluate a PEP 426 environment marker using markerlib.
1544-
Return a boolean indicating the marker result in this environment.
1545-
Raise SyntaxError if marker is invalid.
1546-
"""
1547-
import _markerlib
1548-
1549-
env = cls._translate_metadata2(_markerlib.default_environment())
1550-
try:
1551-
result = _markerlib.interpret(text, env)
1552-
except NameError as e:
1553-
raise SyntaxError(e.args[0])
1554-
return result
1555-
1556-
if 'parser' not in globals():
1557-
# Fall back to less-complete _markerlib implementation if 'parser' module
1558-
# is not available.
1559-
evaluate_marker = _markerlib_evaluate
1560-
1561-
@classmethod
1562-
def interpret(cls, nodelist):
1563-
while len(nodelist)==2: nodelist = nodelist[1]
1564-
try:
1565-
op = cls.get_op(nodelist[0])
1566-
except KeyError:
1567-
raise SyntaxError("Comparison or logical expression expected")
1568-
return op(nodelist)
1404+
def invalid_marker(text):
1405+
"""
1406+
Validate text as a PEP 508 environment marker; return an exception
1407+
if invalid or False otherwise.
1408+
"""
1409+
try:
1410+
evaluate_marker(text)
1411+
except packaging.markers.InvalidMarker as e:
1412+
e.filename = None
1413+
e.lineno = None
1414+
return e
1415+
return False
15691416

1570-
@classmethod
1571-
def evaluate(cls, nodelist):
1572-
while len(nodelist)==2: nodelist = nodelist[1]
1573-
kind = nodelist[0]
1574-
name = nodelist[1]
1575-
if kind==token.NAME:
1576-
try:
1577-
op = cls.values[name]
1578-
except KeyError:
1579-
raise SyntaxError("Unknown name %r" % name)
1580-
return op()
1581-
if kind==token.STRING:
1582-
s = nodelist[1]
1583-
if not cls._safe_string(s):
1584-
raise SyntaxError(
1585-
"Only plain strings allowed in environment markers")
1586-
return s[1:-1]
1587-
msg = "Language feature not supported in environment markers"
1588-
raise SyntaxError(msg)
15891417

1590-
@staticmethod
1591-
def _safe_string(cand):
1592-
return (
1593-
cand[:1] in "'\"" and
1594-
not cand.startswith('"""') and
1595-
not cand.startswith("'''") and
1596-
'\\' not in cand
1597-
)
1418+
def evaluate_marker(text, extra=None):
1419+
"""
1420+
Evaluate a PEP 508 environment marker.
1421+
Return a boolean indicating the marker result in this environment.
1422+
Raise InvalidMarker if marker is invalid.
1423+
This implementation uses the 'pyparsing' module.
1424+
"""
1425+
marker = packaging.markers.Marker(text)
1426+
return marker.evaluate()
15981427

1599-
invalid_marker = MarkerEvaluation.is_invalid_marker
1600-
evaluate_marker = MarkerEvaluation.evaluate_marker
16011428

16021429
class NullProvider:
16031430
"""Try to implement resources and metadata for arbitrary PEP 302 loaders"""

0 commit comments

Comments
 (0)