Skip to content
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
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ insert_final_newline = true
indent_style = space
indent_size = 4
charset = utf-8
max_line_length = 180
max_line_length = 120

[*.{bat,cmd,ps1}]
end_of_line = crlf
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ In short, this is how that works.
```

5. Start making your changes to the **master** branch (or branch off of it).
6. Auto-format your code using `black -l 180 <path_to_source_file>`.
6. Auto-format your code using `black <path_to_source_file>`.
7. Make sure all tests still pass:

```bash
Expand Down
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ include AUTHORS.md
include CHANGELOG.md
include requirements.txt
include conftest.py
include pyproject.toml

exclude requirements-dev.txt
exclude pytest.ini .bumpversion.cfg .editorconfig
Expand Down
4 changes: 2 additions & 2 deletions docs/devguide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ The procedure for submitting a PR is the following.
Style guide
===========

Please run `black -l 180 <path_to_source_file>` to auto-format your code.
Please run `black <path_to_source_file>` to auto-format your code.

The command ``invoke lint`` runs the entire codebase through ``flake8``.
As described in the `docs <https://flake8.pycqa.org/en/latest/manpage.html>`_,
Expand All @@ -88,7 +88,7 @@ https://flake8.pycqa.org/en/latest/user/error-codes.html
The PEP-0008 style guide is available here:
https://www.python.org/dev/peps/pep-0008/

Note that the maximum line length is set to 180 rather 79 in the ``setup.cfg`` of the repo.
Note that the maximum line length is set to 120 rather 79 in the ``setup.cfg`` of the repo.


Naming conventions
Expand Down
26 changes: 26 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[tool.black]
line-length = 120

[tool.pytest.ini_options]
minversion = "6.0"
testpaths = ["tests", "src/compas"]
python_files = [
"test_*.py",
"tests.py"
]
addopts = "-ra --strict --doctest-modules --doctest-glob=*.rst --tb=short"
doctest_optionflags= "NORMALIZE_WHITESPACE IGNORE_EXCEPTION_DETAIL ALLOW_UNICODE ALLOW_BYTES NUMBER"
filterwarnings = "ignore::DeprecationWarning"

[tool.isort]
line_length = 120
multi_line_output = 3
include_trailing_comma = true
force_grid_wrap = 0
use_parentheses = true
force_single_line = true
ensure_newline_before_comments = true
known_first_party = "compas"
default_section = "THIRDPARTY"
forced_separate = "test_compas"
skip = ["__init__.py"]
34 changes: 2 additions & 32 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,13 @@
universal = 1

[flake8]
max-line-length = 180
max-line-length = 120
exclude = */migrations/*
extend-ignore = E203

[doc8]
max-line-length = 180
max-line-length = 120
ignore = D001

[pydocstyle]
convention = numpy

[tool:pytest]
testpaths =
tests
src/compas
norecursedirs =
migrations
python_files =
test_*.py
*_test.py
tests.py
addopts =
-ra
--strict
--doctest-glob=\*.rst
--tb=short
doctest_optionflags =
NORMALIZE_WHITESPACE
IGNORE_EXCEPTION_DETAIL
ALLOW_UNICODE
ALLOW_BYTES
NUMBER

[isort]
force_single_line = True
line_length = 180
known_first_party = compas
default_section = THIRDPARTY
forced_separate = test_compas
skip = migrations, __init__.py
12 changes: 3 additions & 9 deletions src/compas/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,9 +240,7 @@ def get(filename):
if os.path.exists(localpath):
return localpath
else:
return "https://raw.githubusercontent.com/compas-dev/compas/main/src/compas/data/samples/{}".format(
filename
)
return "https://raw.githubusercontent.com/compas-dev/compas/main/src/compas/data/samples/{}".format(filename)


def get_bunny(localstorage=None):
Expand Down Expand Up @@ -288,14 +286,10 @@ def get_bunny(localstorage=None):
os.makedirs(localstorage)

if not os.path.isdir(localstorage):
raise Exception(
"Local storage location does not exist: {}".format(localstorage)
)
raise Exception("Local storage location does not exist: {}".format(localstorage))

if not os.access(localstorage, os.W_OK):
raise Exception(
"Local storage location is not writable: {}".format(localstorage)
)
raise Exception("Local storage location is not writable: {}".format(localstorage))

bunny = compas._os.absjoin(localstorage, "bunny/reconstruction/bun_zipper.ply")
destination = compas._os.absjoin(localstorage, "bunny.tar.gz")
Expand Down
6 changes: 1 addition & 5 deletions src/compas/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,7 @@
print("Yay! COMPAS is installed correctly!")
print()
print("COMPAS: {}".format(compas.__version__))
print(
"Python: {} ({})".format(
platform.python_version(), platform.python_implementation()
)
)
print("Python: {} ({})".format(platform.python_version(), platform.python_implementation()))

if pkg_resources:
working_set = pkg_resources.working_set
Expand Down
31 changes: 7 additions & 24 deletions src/compas/_os.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,9 +194,7 @@ def select_python(python_executable):
either `python` or `pythonw`.
"""
if PYTHON_DIRECTORY and os.path.exists(PYTHON_DIRECTORY):
python_executables = (
[python_executable] if python_executable else ["pythonw", "python"]
)
python_executables = [python_executable] if python_executable else ["pythonw", "python"]

for python_exe in python_executables:
python = os.path.join(PYTHON_DIRECTORY, python_exe)
Expand Down Expand Up @@ -284,9 +282,7 @@ def _realpath_ipy_win(path):
parent_path = os.path.join(path, "..")

args = 'dir /c "{}" /Al'.format(parent_path)
process = subprocess.Popen(
args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
)
process = subprocess.Popen(args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

output, _error = process.communicate()
matches = SYMLINK_REGEX.finditer(output)
Expand All @@ -302,9 +298,7 @@ def _realpath_ipy_win(path):

def _realpath_ipy_posix(path):
args = 'readlink -f "{}"'.format(path)
process = subprocess.Popen(
args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
)
process = subprocess.Popen(args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output, _error = process.communicate()
return output

Expand All @@ -323,14 +317,8 @@ def _polyfill_symlinks(symlinks, raise_on_error):
mklink_cmd.write("ECHO ret=%symlink_result%\n")
for i, (source, link_name) in enumerate(symlinks):
dir_symlink_arg = "/D" if os.path.isdir(source) else ""
mklink_cmd.write(
"mklink {} {}\n".format(
dir_symlink_arg, subprocess.list2cmdline([link_name, source])
)
)
mklink_cmd.write(
"IF %ERRORLEVEL% EQU 0 SET /A symlink_result += {} \n".format(2**i)
)
mklink_cmd.write("mklink {} {}\n".format(dir_symlink_arg, subprocess.list2cmdline([link_name, source])))
mklink_cmd.write("IF %ERRORLEVEL% EQU 0 SET /A symlink_result += {} \n".format(2**i))

mklink_cmd.write("EXIT /B %symlink_result%\n")

Expand Down Expand Up @@ -547,9 +535,7 @@ def _run_command_as_admin(command, arguments):

with open(temp_path, "w") as remove_symlink_cmd:
remove_symlink_cmd.write("@echo off\n")
remove_symlink_cmd.write(
"{} {}\n".format(command, subprocess.list2cmdline(arguments))
)
remove_symlink_cmd.write("{} {}\n".format(command, subprocess.list2cmdline(arguments)))

_run_as_admin([temp_path])

Expand Down Expand Up @@ -588,10 +574,7 @@ def _run_as_admin(command):
ctypes.windll.kernel32.WaitForSingleObject(process_handle, INFINITE)

ret = ctypes.wintypes.DWORD()
if (
ctypes.windll.kernel32.GetExitCodeProcess(process_handle, ctypes.byref(ret))
== 0
):
if ctypes.windll.kernel32.GetExitCodeProcess(process_handle, ctypes.byref(ret)) == 0:
raise RuntimeError("Failed to retrieve exit code")

return ret.value
Expand Down
4 changes: 1 addition & 3 deletions src/compas/artists/artist.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,7 @@ def _get_artist_cls(data, **kwargs):

if cls is None:
raise DataArtistNotRegistered(
"No artist is registered for this data type: {} in this context: {}".format(
dtype, Artist.CONTEXT
)
"No artist is registered for this data type: {} in this context: {}".format(dtype, Artist.CONTEXT)
)

return cls
Expand Down
8 changes: 2 additions & 6 deletions src/compas/artists/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,7 @@ class NoArtistContextError(Exception):

def __init__(self):
error_message = "No context defined."
error_message += (
"\n\nThis usually means that the script that you are running requires"
)
error_message += (
"\na CAD environment but it is being ran as a standalone script"
)
error_message += "\n\nThis usually means that the script that you are running requires"
error_message += "\na CAD environment but it is being ran as a standalone script"
error_message += "\n(ie. from the command line or code editor)."
super(NoArtistContextError, self).__init__(error_message)
43 changes: 9 additions & 34 deletions src/compas/artists/meshartist.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,15 +106,7 @@ class MeshArtist(Artist):
default_edgewidth = 1.0

def __init__(
self,
mesh,
vertices=None,
edges=None,
faces=None,
vertexcolor=None,
edgecolor=None,
facecolor=None,
**kwargs
self, mesh, vertices=None, edges=None, faces=None, vertexcolor=None, edgecolor=None, facecolor=None, **kwargs
):
super(MeshArtist, self).__init__()

Expand Down Expand Up @@ -197,10 +189,7 @@ def faces(self, faces):
@property
def vertex_xyz(self):
if self._vertex_xyz is None:
return {
vertex: self.mesh.vertex_attributes(vertex, "xyz")
for vertex in self.mesh.vertices()
}
return {vertex: self.mesh.vertex_attributes(vertex, "xyz") for vertex in self.mesh.vertices()}
return self._vertex_xyz

@vertex_xyz.setter
Expand All @@ -218,18 +207,14 @@ def vertex_text(self, text):
if text == "key":
self._vertex_text = {vertex: str(vertex) for vertex in self.mesh.vertices()}
elif text == "index":
self._vertex_text = {
vertex: str(index) for index, vertex in enumerate(self.mesh.vertices())
}
self._vertex_text = {vertex: str(index) for index, vertex in enumerate(self.mesh.vertices())}
elif isinstance(text, dict):
self._vertex_text = text

@property
def vertex_size(self):
if not self._vertex_size:
self._vertex_size = {
vertex: self.default_vertexsize for vertex in self.mesh.vertices()
}
self._vertex_size = {vertex: self.default_vertexsize for vertex in self.mesh.vertices()}
return self._vertex_size

@vertex_size.setter
Expand All @@ -242,30 +227,22 @@ def vertex_size(self, vertexsize):
@property
def edge_text(self):
if self._edge_text is None:
self._edge_text = {
edge: "{}-{}".format(*edge) for edge in self.mesh.edges()
}
self._edge_text = {edge: "{}-{}".format(*edge) for edge in self.mesh.edges()}
return self._edge_text

@edge_text.setter
def edge_text(self, text):
if text == "key":
self._edge_text = {
edge: "{}-{}".format(*edge) for edge in self.mesh.edges()
}
self._edge_text = {edge: "{}-{}".format(*edge) for edge in self.mesh.edges()}
elif text == "index":
self._edge_text = {
edge: str(index) for index, edge in enumerate(self.mesh.edges())
}
self._edge_text = {edge: str(index) for index, edge in enumerate(self.mesh.edges())}
elif isinstance(text, dict):
self._edge_text = text

@property
def edge_width(self):
if not self._edge_width:
self._edge_width = {
edge: self.default_edgewidth for edge in self.mesh.edges()
}
self._edge_width = {edge: self.default_edgewidth for edge in self.mesh.edges()}
return self._edge_width

@edge_width.setter
Expand All @@ -286,9 +263,7 @@ def face_text(self, text):
if text == "key":
self._face_text = {face: str(face) for face in self.mesh.faces()}
elif text == "index":
self._face_text = {
face: str(index) for index, face in enumerate(self.mesh.faces())
}
self._face_text = {face: str(index) for index, face in enumerate(self.mesh.faces())}
elif isinstance(text, dict):
self._face_text = text

Expand Down
Loading