Skip to content

Commit

Permalink
fix: [SUP-1872] fixed pipfile parser
Browse files Browse the repository at this point in the history
  • Loading branch information
gemaxim committed Sep 12, 2023
1 parent 6099b74 commit a1f659d
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 4 deletions.
24 changes: 20 additions & 4 deletions pysrc/pipfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,35 @@ def __init__(self, name):
def from_dict(cls, name, requirement_dict, pos_in_toml):
req = cls(name)

req.version = requirement_dict.get('version')
req.editable = requirement_dict.get('editable', False)
req.version = parse_req(requirement_dict.get('version'))
req.editable = parse_req(requirement_dict.get('editable', False))
for vcs in ['git', 'hg', 'svn', 'bzr']:
if vcs in requirement_dict:
req.vcs = vcs
req.vcs_uri = requirement_dict[vcs]
break
req.markers = requirement_dict.get('markers')
req.markers = parse_req(requirement_dict.get('markers'))
# proper file name to be injected into provenance by the calling code
req.provenance = ('Pipfile', pos_in_toml[0], pos_in_toml[0])

return req

'''
The toml parser returns each requirement as a tuple
of the value and ending position, for multiple requirements
e.g.
{
'version': ('*', (9, 23)),
'markers': ("sys_platform == 'linux' ; python_version != '3.4'", (8, 36))
} for entry
waitress = {version = "*", markers="sys_platform == 'linux' ; python_version != '3.4'"}
This functions returns the value without the position for one such instance
e.g. parse_req(("sys_platform == 'linux' ; python_version != '3.4'", (8, 36))) returns "sys_platform == 'linux' ; python_version != '3.4'"
'''
def parse_req(pipfile_req):
if type(pipfile_req) is tuple:
return pipfile_req[0]
return pipfile_req

def val_with_pos(kind, text, value, pos):
return (value, pos)

Expand Down
75 changes: 75 additions & 0 deletions pysrc/test_pipfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# run with:
# cd pysrc; python3 test_pipfile.py; cd ..

from pipfile import PipfileRequirement, parse
from collections import namedtuple

import unittest

try:
from mock import patch
except:
from unittest.mock import patch

class TestPipfileRequirement(unittest.TestCase):
def test_init(self):
req = PipfileRequirement("example")
self.assertEqual(req.name, "example")
self.assertFalse(req.editable)
self.assertIsNone(req.vcs)
self.assertIsNone(req.vcs_uri)
self.assertIsNone(req.version)
self.assertIsNone(req.markers)
self.assertIsNone(req.provenance)

def test_from_dict(self):
requirement_dict = {
'version': '*',
'editable': True,
'git': 'git_uri',
'markers': 'sys_platform == "linux" ; python_version != "3.4"'
}
pos_in_toml = (1, 2)
req = PipfileRequirement.from_dict("example", requirement_dict, pos_in_toml)
self.assertEqual(req.name, "example")
self.assertTrue(req.editable)
self.assertEqual(req.vcs, "git")
self.assertEqual(req.vcs_uri, "git_uri")
self.assertEqual(req.version, "*")
self.assertEqual(req.markers, 'sys_platform == "linux" ; python_version != "3.4"')
self.assertEqual(req.provenance, ('Pipfile', 1, 1))

def test_parse(self):
pipfile_content = """
[packages]
requests = "*"
flask = { version = "1.0", markers = "python_version < '3.7'" }
[dev-packages]
pytest = "*"
"""
parsed_data = parse(pipfile_content)

self.assertIn('packages', parsed_data)
self.assertIn('dev-packages', parsed_data)

packages = parsed_data['packages']
self.assertIsInstance(packages, list)
self.assertEqual(len(packages), 2)

dev_packages = parsed_data['dev-packages']
self.assertIsInstance(dev_packages, list)
self.assertEqual(len(dev_packages), 1)

self.assertEqual(packages[0].name, 'flask')
self.assertEqual(packages[0].editable, False)
self.assertEqual(packages[0].vcs, None)
self.assertEqual(packages[0].vcs_uri, None)
self.assertEqual(packages[0].version, '1.0')
self.assertEqual(packages[0].markers, 'python_version < \'3.7\'')
self.assertEqual(packages[0].provenance, ('Pipfile', 4, 4))



if __name__ == '__main__':
unittest.main()

0 comments on commit a1f659d

Please sign in to comment.