Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
In what follows python
is an alias for python3.6
or pypy3.6
or any later version (python3.7
, pypy3.7
and so on).
Install the latest pip
& setuptools
packages versions
python -m pip install --upgrade pip setuptools
Download and install the latest stable version from PyPI
repository
python -m pip install --upgrade hypothesis_geometry
Download the latest version from GitHub
repository
git clone https://github.com/lycantropos/hypothesis_geometry.git
cd hypothesis_geometry
Install dependencies
python -m pip install -r requirements.txt
Install
python setup.py install
With setup
>>> from ground.base import get_context
>>> from hypothesis import strategies
>>> from hypothesis_geometry import planar
>>> context = get_context()
>>> Contour = context.contour_cls
>>> Empty = context.empty_cls
>>> Mix = context.mix_cls
>>> Multipoint = context.multipoint_cls
>>> Multipolygon = context.multipolygon_cls
>>> Multisegment = context.multisegment_cls
>>> Point = context.point_cls
>>> Polygon = context.polygon_cls
>>> Segment = context.segment_cls
>>> min_coordinate, max_coordinate = -100, 100
>>> coordinates_type = int
>>> coordinates = strategies.integers(min_coordinate, max_coordinate)
>>> import warnings
>>> from hypothesis.errors import NonInteractiveExampleWarning
>>> # ignore hypothesis warnings caused by `example` method call
... warnings.filterwarnings('ignore', category=NonInteractiveExampleWarning)
let's take a look at what can be generated and how.
>>> empty_geometries = planar.empty_geometries()
>>> empty = empty_geometries.example()
>>> isinstance(empty, Empty)
True
>>> points = planar.points(coordinates)
>>> point = points.example()
>>> isinstance(point, Point)
True
>>> (isinstance(point.x, coordinates_type)
... and isinstance(point.y, coordinates_type))
True
>>> (min_coordinate <= point.x <= max_coordinate
... and min_coordinate <= point.y <= max_coordinate)
True
>>> min_size, max_size = 5, 10
>>> multipoints = planar.multipoints(coordinates,
... min_size=min_size,
... max_size=max_size)
>>> multipoint = multipoints.example()
>>> isinstance(multipoint, Multipoint)
True
>>> min_size <= len(multipoint.points) <= max_size
True
>>> all(isinstance(point.x, coordinates_type)
... and isinstance(point.y, coordinates_type)
... for point in multipoint.points)
True
>>> all(min_coordinate <= point.x <= max_coordinate
... and min_coordinate <= point.y <= max_coordinate
... for point in multipoint.points)
True
>>> segments = planar.segments(coordinates)
>>> segment = segments.example()
>>> isinstance(segment, Segment)
True
>>> (isinstance(segment.start.x, coordinates_type)
... and isinstance(segment.start.y, coordinates_type)
... and isinstance(segment.end.x, coordinates_type)
... and isinstance(segment.end.y, coordinates_type))
True
>>> (min_coordinate <= segment.start.x <= max_coordinate
... and min_coordinate <= segment.start.y <= max_coordinate
... and min_coordinate <= segment.end.x <= max_coordinate
... and min_coordinate <= segment.end.y <= max_coordinate)
True
>>> min_size, max_size = 5, 10
>>> multisegments = planar.multisegments(coordinates,
... min_size=min_size,
... max_size=max_size)
>>> multisegment = multisegments.example()
>>> isinstance(multisegment, Multisegment)
True
>>> min_size <= len(multisegment.segments) <= max_size
True
>>> all(isinstance(segment.start.x, coordinates_type)
... and isinstance(segment.start.y, coordinates_type)
... and isinstance(segment.end.x, coordinates_type)
... and isinstance(segment.end.y, coordinates_type)
... for segment in multisegment.segments)
True
>>> all(min_coordinate <= segment.start.x <= max_coordinate
... and min_coordinate <= segment.start.y <= max_coordinate
... and min_coordinate <= segment.end.x <= max_coordinate
... and min_coordinate <= segment.end.y <= max_coordinate
... for segment in multisegment.segments)
True
>>> min_size, max_size = 5, 10
>>> contours = planar.contours(coordinates,
... min_size=min_size,
... max_size=max_size)
>>> contour = contours.example()
>>> isinstance(contour, Contour)
True
>>> min_size <= len(contour.vertices) <= max_size
True
>>> all(isinstance(vertex.x, coordinates_type)
... and isinstance(vertex.y, coordinates_type)
... for vertex in contour.vertices)
True
>>> all(min_coordinate <= vertex.x <= max_coordinate
... and min_coordinate <= vertex.y <= max_coordinate
... for vertex in contour.vertices)
True
also planar.concave_contours
& planar.convex_contours
options are available.
>>> min_size, max_size = 5, 10
>>> min_contour_size, max_contour_size = 4, 8
>>> multicontours = planar.multicontours(coordinates,
... min_size=min_size,
... max_size=max_size,
... min_contour_size=min_contour_size,
... max_contour_size=max_contour_size)
>>> multicontour = multicontours.example()
>>> isinstance(multicontour, list)
True
>>> all(isinstance(contour, Contour) for contour in multicontour)
True
>>> min_size <= len(multicontour) <= max_size
True
>>> all(min_contour_size <= len(contour.vertices) <= max_contour_size
... for contour in multicontour)
True
>>> all(isinstance(vertex.x, coordinates_type)
... and isinstance(vertex.y, coordinates_type)
... for contour in multicontour
... for vertex in contour.vertices)
True
>>> all(min_coordinate <= vertex.x <= max_coordinate
... and min_coordinate <= vertex.y <= max_coordinate
... for contour in multicontour
... for vertex in contour.vertices)
True
>>> min_size, max_size = 5, 10
>>> min_holes_size, max_holes_size = 1, 3
>>> min_hole_size, max_hole_size = 4, 8
>>> polygons = planar.polygons(coordinates,
... min_size=min_size,
... max_size=max_size,
... min_holes_size=min_holes_size,
... max_holes_size=max_holes_size,
... min_hole_size=min_hole_size,
... max_hole_size=max_hole_size)
>>> polygon = polygons.example()
>>> isinstance(polygon, Polygon)
True
>>> min_size <= len(polygon.border.vertices) <= max_size
True
>>> min_holes_size <= len(polygon.holes) <= max_holes_size
True
>>> all(min_hole_size <= len(hole.vertices) <= max_hole_size for hole in polygon.holes)
True
>>> polygon_contours = [polygon.border, *polygon.holes]
>>> all(isinstance(vertex.x, coordinates_type)
... and isinstance(vertex.y, coordinates_type)
... for contour in polygon_contours
... for vertex in contour.vertices)
True
>>> all(min_coordinate <= vertex.x <= max_coordinate
... and min_coordinate <= vertex.y <= max_coordinate
... for contour in polygon_contours
... for vertex in contour.vertices)
True
>>> min_size, max_size = 2, 5
>>> min_border_size, max_border_size = 5, 10
>>> min_holes_size, max_holes_size = 1, 3
>>> min_hole_size, max_hole_size = 4, 8
>>> multipolygons = planar.multipolygons(coordinates,
... min_size=min_size,
... max_size=max_size,
... min_border_size=min_border_size,
... max_border_size=max_border_size,
... min_holes_size=min_holes_size,
... max_holes_size=max_holes_size,
... min_hole_size=min_hole_size,
... max_hole_size=max_hole_size)
>>> multipolygon = multipolygons.example()
>>> isinstance(multipolygon, Multipolygon)
True
>>> min_size <= len(multipolygon.polygons) <= max_size
True
>>> all(min_border_size <= len(polygon.border.vertices) <= max_border_size
... and min_holes_size <= len(polygon.holes) <= max_holes_size
... and all(min_hole_size <= len(hole.vertices) <= max_hole_size
... for hole in polygon.holes)
... for polygon in multipolygon.polygons)
True
>>> all(all(isinstance(vertex.x, coordinates_type)
... and isinstance(vertex.y, coordinates_type)
... for vertex in polygon.border.vertices)
... and all(isinstance(vertex.x, coordinates_type)
... and isinstance(vertex.y, coordinates_type)
... for hole in polygon.holes
... for vertex in hole.vertices)
... for polygon in multipolygon.polygons)
True
>>> all(all(min_coordinate <= vertex.x <= max_coordinate
... and min_coordinate <= vertex.y <= max_coordinate
... for vertex in polygon.border.vertices)
... and all(min_coordinate <= vertex.x <= max_coordinate
... and min_coordinate <= vertex.y <= max_coordinate
... for hole in polygon.holes
... for vertex in hole.vertices)
... for polygon in multipolygon.polygons)
True
>>> min_points_size, max_points_size = 2, 3
>>> min_segments_size, max_segments_size = 1, 4
>>> min_polygons_size, max_polygons_size = 0, 5
>>> min_polygon_border_size, max_polygon_border_size = 5, 10
>>> min_polygon_holes_size, max_polygon_holes_size = 1, 4
>>> min_polygon_hole_size, max_polygon_hole_size = 3, 5
>>> mixes = planar.mixes(coordinates,
... min_points_size=min_points_size,
... max_points_size=max_points_size,
... min_segments_size=min_segments_size,
... max_segments_size=max_segments_size,
... min_polygons_size=min_polygons_size,
... max_polygons_size=max_polygons_size,
... min_polygon_border_size=min_polygon_border_size,
... max_polygon_border_size=max_polygon_border_size,
... min_polygon_holes_size=min_polygon_holes_size,
... max_polygon_holes_size=max_polygon_holes_size,
... min_polygon_hole_size=min_polygon_hole_size,
... max_polygon_hole_size=max_polygon_hole_size)
>>> mix = mixes.example()
>>> isinstance(mix, Mix)
True
>>> isinstance(mix.discrete, (Empty, Multipoint))
True
>>> points = [] if isinstance(mix.discrete, Empty) else mix.discrete.points
>>> min_points_size <= len(points) <= max_points_size
True
>>> all(isinstance(point.x, coordinates_type)
... and isinstance(point.y, coordinates_type)
... for point in points)
True
>>> all(min_coordinate <= point.x <= max_coordinate
... and min_coordinate <= point.y <= max_coordinate
... for point in points)
True
>>> isinstance(mix.linear, (Empty, Segment, Contour, Multisegment))
True
>>> segments = ([]
... if isinstance(mix.linear, Empty)
... else ([mix.linear]
... if isinstance(mix.linear, Segment)
... else (mix.linear.segments
... if isinstance(mix.linear, Multisegment)
... else context.contour_edges(mix.linear))))
>>> min_segments_size <= len(segments) <= max_segments_size
True
>>> all(isinstance(segment.start.x, coordinates_type)
... and isinstance(segment.start.y, coordinates_type)
... and isinstance(segment.end.x, coordinates_type)
... and isinstance(segment.end.y, coordinates_type)
... for segment in segments)
True
>>> all(min_coordinate <= segment.start.x <= max_coordinate
... and min_coordinate <= segment.start.y <= max_coordinate
... and min_coordinate <= segment.end.x <= max_coordinate
... and min_coordinate <= segment.end.y <= max_coordinate
... for segment in segments)
True
>>> isinstance(mix.shaped, (Empty, Polygon, Multipolygon))
True
>>> polygons = ([]
... if isinstance(mix.shaped, Empty)
... else ([mix.shaped]
... if isinstance(mix.shaped, Polygon)
... else mix.shaped.polygons))
>>> min_polygons_size <= len(polygons) <= max_polygons_size
True
>>> all(min_polygon_border_size
... <= len(polygon.border.vertices)
... <= max_polygon_border_size
... and (min_polygon_holes_size
... <= len(polygon.holes)
... <= max_polygon_holes_size)
... and all(min_polygon_hole_size
... <= len(hole.vertices)
... <= max_polygon_hole_size
... for hole in polygon.holes)
... for polygon in polygons)
True
>>> all(all(isinstance(vertex.x, coordinates_type)
... and isinstance(vertex.y, coordinates_type)
... for vertex in polygon.border.vertices)
... and all(isinstance(vertex.x, coordinates_type)
... and isinstance(vertex.y, coordinates_type)
... for hole in polygon.holes
... for vertex in hole.vertices)
... for polygon in polygons)
True
>>> all(all(min_coordinate <= vertex.x <= max_coordinate
... and min_coordinate <= vertex.y <= max_coordinate
... for vertex in polygon.border.vertices)
... and all(min_coordinate <= vertex.x <= max_coordinate
... and min_coordinate <= vertex.y <= max_coordinate
... for hole in polygon.holes
... for vertex in hole.vertices)
... for polygon in polygons)
True
Strategies may be slow depending on domain,
so it may be necessary to add HealthCheck.filter_too_much
, HealthCheck.too_slow
in suppress_health_check
and set deadline
to None
.
Unbounded floating point strategies for coordinates
(like hypothesis.strategies.floats
with unset min_value
/max_value
) do not play well with bounded sizes
and may cause a lot of searching iterations with no success,
so it is recommended to use bounded floating point coordinates with bounded sizes
or unbounded coordinates with unbounded sizes.
decimal.Decimal
coordinates are not supported, because
they seem to be too hard to work with correctly (e.g. sometimes self-intersecting contours arise),
so it is suggested to use float
or fractions.Fraction
instead.
Install bump2version.
Choose which version number category to bump following semver specification.
Test bumping version
bump2version --dry-run --verbose $CATEGORY
where $CATEGORY
is the target version number category name, possible
values are patch
/minor
/major
.
Bump version
bump2version --verbose $CATEGORY
This will set version to major.minor.patch-alpha
.
Test bumping version
bump2version --dry-run --verbose release
Bump version
bump2version --verbose release
This will set version to major.minor.patch
.
Install dependencies
python -m pip install -r requirements-tests.txt
Plain
pytest
Inside Docker
container:
CPython
docker-compose --file docker-compose.cpython.yml up
PyPy
docker-compose --file docker-compose.pypy.yml up
Bash
script:
with CPython
./run-tests.sh
or
./run-tests.sh cpython
with PyPy
./run-tests.sh pypy
PowerShell
script:
CPython
.\run-tests.ps1
or
.\run-tests.ps1 cpython
PyPy
.\run-tests.ps1 pypy
FAQs
Unknown package
We found that hypothesis-geometry demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.