Skip to content

Commit 618ad9f

Browse files
authored
Merge pull request #287 from emarondan/adding-pre-commit
Add pre-commit
2 parents 0475327 + 047282b commit 618ad9f

20 files changed

+124
-272
lines changed

.bandit.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
skips:
22
- B101
3+
- B311
34
- B320
45
- B410
6+
exclude_dirs: ['tests']

.flake8

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ per-file-ignores =
99
setup.py:E501
1010
tests/test_selector.py:E501
1111
tests/test_selector_csstranslator.py:E501
12+
tests/test_selector_jmespath.py:E501
1213
tests/test_utils.py:E501
1314
tests/test_xpathfuncs.py:E501
1415
tests/typing/*.py:E,F

.git-blame-ignore-revs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# applying pre-commit hooks to the project
2+
a57c23e3b7be0f001595bd8767fe05e40a66e730

.github/workflows/checks.yml

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,7 @@ jobs:
1010
include:
1111
- python-version: "3.12"
1212
env:
13-
TOXENV: security
14-
- python-version: "3.12"
15-
env:
16-
TOXENV: flake8
13+
TOXENV: pre-commit
1714
- python-version: "3.12"
1815
env:
1916
TOXENV: pylint
@@ -23,9 +20,6 @@ jobs:
2320
- python-version: "3.12"
2421
env:
2522
TOXENV: typing
26-
- python-version: "3.12"
27-
env:
28-
TOXENV: black
2923
- python-version: "3.12"
3024
env:
3125
TOXENV: twinecheck

.isort.cfg

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[settings]
2+
profile = black

.pre-commit-config.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
repos:
2+
- repo: https://github.com/PyCQA/bandit
3+
rev: 1.7.7
4+
hooks:
5+
- id: bandit
6+
args: [-r, -c, .bandit.yml]
7+
- repo: https://github.com/PyCQA/flake8
8+
rev: 7.0.0
9+
hooks:
10+
- id: flake8
11+
- repo: https://github.com/psf/black.git
12+
rev: 24.1.1
13+
hooks:
14+
- id: black
15+
- repo: https://github.com/pycqa/isort
16+
rev: 5.13.2
17+
hooks:
18+
- id: isort

docs/conf.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import os
44
import sys
55

6-
76
# Get the project root dir, which is the parent dir of this
87
cwd = os.getcwd()
98
project_root = os.path.dirname(cwd)
@@ -13,8 +12,7 @@
1312
# version is used.
1413
sys.path.insert(0, project_root)
1514

16-
import parsel
17-
15+
import parsel # noqa: E402
1816

1917
# -- General configuration ---------------------------------------------
2018

@@ -98,10 +96,9 @@
9896
# One entry per manual page. List of tuples
9997
# (source start file, name, description, authors, manual section).
10098
man_pages = [
101-
("index", "parsel", "Parsel Documentation", ["Scrapy Project"], 1)
99+
("index", "parsel", "Parsel Documentation", ["Scrapy Project"], 1),
102100
]
103101

104-
105102
# -- Options for Texinfo output ----------------------------------------
106103

107104
# Grouping the document tree into Texinfo files. List of tuples

parsel/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
"xpathfuncs",
1414
]
1515

16-
from parsel.selector import Selector, SelectorList # NOQA
17-
from parsel.csstranslator import css2xpath # NOQA
1816
from parsel import xpathfuncs # NOQA
17+
from parsel.csstranslator import css2xpath # NOQA
18+
from parsel.selector import Selector, SelectorList # NOQA
1919

2020
xpathfuncs.setup()

parsel/csstranslator.py

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@
33

44
from cssselect import GenericTranslator as OriginalGenericTranslator
55
from cssselect import HTMLTranslator as OriginalHTMLTranslator
6-
from cssselect.xpath import XPathExpr as OriginalXPathExpr
7-
from cssselect.xpath import ExpressionError
86
from cssselect.parser import Element, FunctionalPseudoElement, PseudoElement
9-
7+
from cssselect.xpath import ExpressionError
8+
from cssselect.xpath import XPathExpr as OriginalXPathExpr
109

1110
if TYPE_CHECKING:
1211
# typing.Self requires Python 3.11
@@ -25,9 +24,7 @@ def from_xpath(
2524
textnode: bool = False,
2625
attribute: Optional[str] = None,
2726
) -> "Self":
28-
x = cls(
29-
path=xpath.path, element=xpath.element, condition=xpath.condition
30-
)
27+
x = cls(path=xpath.path, element=xpath.element, condition=xpath.condition)
3128
x.textnode = textnode
3229
x.attribute = attribute
3330
return x
@@ -82,9 +79,7 @@ class TranslatorMixin:
8279
Currently supported pseudo-elements are ``::text`` and ``::attr(ATTR_NAME)``.
8380
"""
8481

85-
def xpath_element(
86-
self: TranslatorProtocol, selector: Element
87-
) -> XPathExpr:
82+
def xpath_element(self: TranslatorProtocol, selector: Element) -> XPathExpr:
8883
# https://github.com/python/mypy/issues/12344
8984
xpath = super().xpath_element(selector) # type: ignore[safe-super]
9085
return XPathExpr.from_xpath(xpath)
@@ -104,7 +99,9 @@ def xpath_pseudo_element(
10499
)
105100
xpath = method(xpath, pseudo_element)
106101
else:
107-
method_name = f"xpath_{pseudo_element.replace('-', '_')}_simple_pseudo_element"
102+
method_name = (
103+
f"xpath_{pseudo_element.replace('-', '_')}_simple_pseudo_element"
104+
)
108105
method = getattr(self, method_name, None)
109106
if not method:
110107
raise ExpressionError(
@@ -121,30 +118,22 @@ def xpath_attr_functional_pseudo_element(
121118
raise ExpressionError(
122119
f"Expected a single string or ident for ::attr(), got {function.arguments!r}" # noqa: E231
123120
)
124-
return XPathExpr.from_xpath(
125-
xpath, attribute=function.arguments[0].value
126-
)
121+
return XPathExpr.from_xpath(xpath, attribute=function.arguments[0].value)
127122

128-
def xpath_text_simple_pseudo_element(
129-
self, xpath: OriginalXPathExpr
130-
) -> XPathExpr:
123+
def xpath_text_simple_pseudo_element(self, xpath: OriginalXPathExpr) -> XPathExpr:
131124
"""Support selecting text nodes using ::text pseudo-element"""
132125
return XPathExpr.from_xpath(xpath, textnode=True)
133126

134127

135128
class GenericTranslator(TranslatorMixin, OriginalGenericTranslator):
136129
@lru_cache(maxsize=256)
137-
def css_to_xpath(
138-
self, css: str, prefix: str = "descendant-or-self::"
139-
) -> str:
130+
def css_to_xpath(self, css: str, prefix: str = "descendant-or-self::") -> str:
140131
return super().css_to_xpath(css, prefix)
141132

142133

143134
class HTMLTranslator(TranslatorMixin, OriginalHTMLTranslator):
144135
@lru_cache(maxsize=256)
145-
def css_to_xpath(
146-
self, css: str, prefix: str = "descendant-or-self::"
147-
) -> str:
136+
def css_to_xpath(self, css: str, prefix: str = "descendant-or-self::") -> str:
148137
return super().css_to_xpath(css, prefix)
149138

150139

parsel/selector.py

Lines changed: 10 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
from .csstranslator import GenericTranslator, HTMLTranslator
3030
from .utils import extract_regex, flatten, iflatten, shorten
3131

32-
3332
_SelectorType = TypeVar("_SelectorType", bound="Selector")
3433
_ParserType = Union[etree.XMLParser, etree.HTMLParser]
3534
# simplified _OutputMethodArg from types-lxml
@@ -135,18 +134,14 @@ def __getitem__(
135134
) -> Union[_SelectorType, "SelectorList[_SelectorType]"]:
136135
o = super().__getitem__(pos)
137136
if isinstance(pos, slice):
138-
return self.__class__(
139-
typing.cast("SelectorList[_SelectorType]", o)
140-
)
137+
return self.__class__(typing.cast("SelectorList[_SelectorType]", o))
141138
else:
142139
return typing.cast(_SelectorType, o)
143140

144141
def __getstate__(self) -> None:
145142
raise TypeError("can't pickle SelectorList objects")
146143

147-
def jmespath(
148-
self, query: str, **kwargs: Any
149-
) -> "SelectorList[_SelectorType]":
144+
def jmespath(self, query: str, **kwargs: Any) -> "SelectorList[_SelectorType]":
150145
"""
151146
Call the ``.jmespath()`` method for each element in this list and return
152147
their results flattened as another :class:`SelectorList`.
@@ -158,9 +153,7 @@ def jmespath(
158153
159154
selector.jmespath('author.name', options=jmespath.Options(dict_cls=collections.OrderedDict))
160155
"""
161-
return self.__class__(
162-
flatten([x.jmespath(query, **kwargs) for x in self])
163-
)
156+
return self.__class__(flatten([x.jmespath(query, **kwargs) for x in self]))
164157

165158
def xpath(
166159
self,
@@ -185,9 +178,7 @@ def xpath(
185178
selector.xpath('//a[href=$url]', url="http://www.example.com")
186179
"""
187180
return self.__class__(
188-
flatten(
189-
[x.xpath(xpath, namespaces=namespaces, **kwargs) for x in self]
190-
)
181+
flatten([x.xpath(xpath, namespaces=namespaces, **kwargs) for x in self])
191182
)
192183

193184
def css(self, query: str) -> "SelectorList[_SelectorType]":
@@ -211,9 +202,7 @@ def re(
211202
Passing ``replace_entities`` as ``False`` switches off these
212203
replacements.
213204
"""
214-
return flatten(
215-
[x.re(regex, replace_entities=replace_entities) for x in self]
216-
)
205+
return flatten([x.re(regex, replace_entities=replace_entities) for x in self])
217206

218207
@typing.overload
219208
def re_first(
@@ -316,9 +305,7 @@ def drop(self) -> None:
316305
_NOT_SET = object()
317306

318307

319-
def _get_root_from_text(
320-
text: str, *, type: str, **lxml_kwargs: Any
321-
) -> etree._Element:
308+
def _get_root_from_text(text: str, *, type: str, **lxml_kwargs: Any) -> etree._Element:
322309
return create_root_node(text, _ctgroup[type]["_parser"], **lxml_kwargs)
323310

324311

@@ -583,9 +570,7 @@ def make_selector(x: Any) -> _SelectorType: # closure function
583570
return self.__class__(root=x, _expr=query)
584571

585572
result = [make_selector(x) for x in result]
586-
return typing.cast(
587-
SelectorList[_SelectorType], self.selectorlist_cls(result)
588-
)
573+
return typing.cast(SelectorList[_SelectorType], self.selectorlist_cls(result))
589574

590575
def xpath(
591576
self: _SelectorType,
@@ -611,9 +596,7 @@ def xpath(
611596
selector.xpath('//a[href=$url]', url="http://www.example.com")
612597
"""
613598
if self.type not in ("html", "xml", "text"):
614-
raise ValueError(
615-
f"Cannot use xpath on a Selector of type {self.type!r}"
616-
)
599+
raise ValueError(f"Cannot use xpath on a Selector of type {self.type!r}")
617600
if self.type in ("html", "xml"):
618601
try:
619602
xpathev = self.root.xpath
@@ -654,9 +637,7 @@ def xpath(
654637
)
655638
for x in result
656639
]
657-
return typing.cast(
658-
SelectorList[_SelectorType], self.selectorlist_cls(result)
659-
)
640+
return typing.cast(SelectorList[_SelectorType], self.selectorlist_cls(result))
660641

661642
def css(self: _SelectorType, query: str) -> SelectorList[_SelectorType]:
662643
"""
@@ -670,9 +651,7 @@ def css(self: _SelectorType, query: str) -> SelectorList[_SelectorType]:
670651
.. _cssselect: https://pypi.python.org/pypi/cssselect/
671652
"""
672653
if self.type not in ("html", "xml", "text"):
673-
raise ValueError(
674-
f"Cannot use css on a Selector of type {self.type!r}"
675-
)
654+
raise ValueError(f"Cannot use css on a Selector of type {self.type!r}")
676655
return self.xpath(self._css2xpath(query))
677656

678657
def _css2xpath(self, query: str) -> str:

0 commit comments

Comments
 (0)