Skip to content

feat: add type hints #130

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ jobs:
run: python -m pip install --upgrade pip setuptools wheel
- name: Install dependencies
run: python -m pip install -r requirements.txt
- name: Install lint dependencies
run: python -m pip install --upgrade mypy
- name: Lint
run: python -m mypy -p linehaul
- name: Install test dependencies
run: python -m pip install pytest pretend hypothesis pyaml
- name: Test
Expand Down
55 changes: 26 additions & 29 deletions linehaul/events/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import cattr

from pyparsing import Literal as L, Word, Optional as OptionalItem
from pyparsing import printables as _printables, restOfLine
from pyparsing import printables as _printables, rest_of_line
from pyparsing import ParseException

from linehaul.ua import UserAgent, parser as user_agents
Expand All @@ -44,11 +44,11 @@ class UnparseableEvent(Exception):
pass


class NullValue:
class _NullValue:
pass


NullValue = NullValue()
NullValue = _NullValue()


printables = "".join(set(_printables + " " + "\t") - {"|", "@"})
Expand All @@ -58,29 +58,26 @@ class NullValue:
AT = L("@").suppress()

NULL = L("(null)")
NULL.setParseAction(lambda s, l, t: NullValue)
NULL.set_parse_action(lambda s, l, t: NullValue)

TIMESTAMP = Word(printables)
TIMESTAMP = TIMESTAMP.setResultsName("timestamp")
TIMESTAMP.setName("Timestamp")
TIMESTAMP = Word(printables).set_name("Timestamp")
TIMESTAMP = TIMESTAMP.set_results_name("timestamp")

COUNTRY_CODE = Word(printables)
COUNTRY_CODE = COUNTRY_CODE.setResultsName("country_code")
COUNTRY_CODE.setName("Country Code")
COUNTRY_CODE = Word(printables).set_name("Country Code")
COUNTRY_CODE = COUNTRY_CODE.set_results_name("country_code")

URL = Word(printables)
URL = URL.setResultsName("url")
URL.setName("URL")
URL = Word(printables).set_name("URL")
URL = URL.set_results_name("url")

REQUEST = TIMESTAMP + PIPE + OptionalItem(COUNTRY_CODE) + PIPE + URL

PROJECT_NAME = NULL | Word(printables)
PROJECT_NAME = PROJECT_NAME.setResultsName("project_name")
PROJECT_NAME.setName("Project Name")
PROJECT_NAME = PROJECT_NAME.set_results_name("project_name")
PROJECT_NAME.set_name("Project Name")

VERSION = NULL | Word(printables)
VERSION = VERSION.setResultsName("version")
VERSION.setName("Version")
VERSION = VERSION.set_results_name("version")
VERSION.set_name("Version")

PACKAGE_TYPE = NULL | (
L("sdist")
Expand All @@ -92,34 +89,34 @@ class NullValue:
| L("bdist_rpm")
| L("bdist_wininst")
)
PACKAGE_TYPE = PACKAGE_TYPE.setResultsName("package_type")
PACKAGE_TYPE.setName("Package Type")
PACKAGE_TYPE = PACKAGE_TYPE.set_results_name("package_type")
PACKAGE_TYPE.set_name("Package Type")

PROJECT = PROJECT_NAME + PIPE + VERSION + PIPE + PACKAGE_TYPE

TLS_PROTOCOL = NULL | Word(printables)
TLS_PROTOCOL = TLS_PROTOCOL.setResultsName("tls_protocol")
TLS_PROTOCOL.setName("TLS Protocol")
TLS_PROTOCOL = TLS_PROTOCOL.set_results_name("tls_protocol")
TLS_PROTOCOL.set_name("TLS Protocol")

TLS_CIPHER = NULL | Word(printables)
TLS_CIPHER = TLS_CIPHER.setResultsName("tls_cipher")
TLS_CIPHER.setName("TLS Cipher")
TLS_CIPHER = TLS_CIPHER.set_results_name("tls_cipher")
TLS_CIPHER.set_name("TLS Cipher")

TLS = TLS_PROTOCOL + PIPE + TLS_CIPHER

USER_AGENT = restOfLine
USER_AGENT = USER_AGENT.setResultsName("user_agent")
USER_AGENT.setName("UserAgent")
USER_AGENT = rest_of_line
USER_AGENT = USER_AGENT.set_results_name("user_agent")
USER_AGENT.set_name("UserAgent")

V1_HEADER = OptionalItem(L("1").suppress() + AT)

MESSAGE_v1 = V1_HEADER + REQUEST + PIPE + PROJECT + PIPE + USER_AGENT
MESSAGE_v1.leaveWhitespace()
MESSAGE_v1.leave_whitespace()

V2_HEADER = L("2").suppress() + AT

MESSAGE_v2 = V2_HEADER + REQUEST + PIPE + TLS + PIPE + PROJECT + PIPE + USER_AGENT
MESSAGE_v2.leaveWhitespace()
MESSAGE_v2.leave_whitespace()

V3_HEADER = L("download")
MESSAGE_v3 = (
Expand Down Expand Up @@ -204,7 +201,7 @@ def _value_or_none(value):

def parse(message):
try:
parsed = MESSAGE.parseString(message, parseAll=True)
parsed = MESSAGE.parse_string(message, parseAll=True)
except ParseException as exc:
raise UnparseableEvent("{!r} {}".format(message, exc)) from None

Expand Down
Empty file added linehaul/py.typed
Empty file.
2 changes: 1 addition & 1 deletion linehaul/ua/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ def BrowserUserAgent():
)


def parse(user_agent):
def parse(user_agent: str) -> UserAgent | None:
try:
return cattr.structure(_parser(user_agent), UserAgent)
except UnableToParse:
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ classifiers = [
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3 :: Only",
"Typing :: Typed",
]

dependencies = [
Expand Down
3 changes: 3 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
[options]
packages = find:

[options.package_data]
* = py.typed