Skip to content
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

Alias detection solution for codemods #106

Merged
merged 4 commits into from
Oct 30, 2023
Merged

Alias detection solution for codemods #106

merged 4 commits into from
Oct 30, 2023

Conversation

andrecsilva
Copy link
Contributor

@andrecsilva andrecsilva commented Oct 27, 2023

Overview

Added new alias detection solution for a few codemods.

Description

Added new alias detection solution for a few codemods (harden-pyyaml, secure-tempfile, and upgrade-ssl-context-minimum-version). This solution will detect whenever a module is aliased and prefer to use the alias for new references to module attributes. Those use a more general tool now included in NameResolutionMixin.

The harden-ruamel and https-connection codemods had working solutions. I've enabled / added new tests for these.

Other codemods (url-sandbox, use-defusedxml) will replace module calls with another call from a drop-in replacement module.
Those will ignore aliases and refer to the replacement module call directly. Since we are referring a third-party module on those, I've elected not to leave the current solution to make the change more explicit.

@andrecsilva andrecsilva changed the title Pyyaml alias Alias detection solution for codemods Oct 27, 2023
@codecov
Copy link

codecov bot commented Oct 27, 2023

Codecov Report

Merging #106 (eed1895) into main (c9634a5) will increase coverage by 0.06%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #106      +/-   ##
==========================================
+ Coverage   95.88%   95.94%   +0.06%     
==========================================
  Files          62       62              
  Lines        2526     2565      +39     
==========================================
+ Hits         2422     2461      +39     
  Misses        104      104              
Files Coverage Δ
src/codemodder/codemods/utils_mixin.py 92.52% <100.00%> (+2.04%) ⬆️
src/core_codemods/harden_pyyaml.py 100.00% <100.00%> (ø)
src/core_codemods/tempfile_mktemp.py 100.00% <100.00%> (ø)
...ore_codemods/upgrade_sslcontext_minimum_version.py 100.00% <100.00%> (ø)

@andrecsilva andrecsilva marked this pull request as ready for review October 27, 2023 12:35
Copy link
Contributor

@clavedeluna clavedeluna left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you address in your PR description why other codemods didn't get this lovely treatment? Grepping alias in tests I'm seeing some that could be easy to add: ruamel, defusedxml, https connection, and url sandbox had some aliasing logic too. If you can address what's the plan with those or add them in this PR that would be helpful context.

alias.evaluated_name,
):
return (import_node, alias)
return None
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

surprised pylint nor mypy didn't complain but all returns of a func should return the same len, so this should be (None, None)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The return type is annotated as Optional[Tuple[...]], that's the reason.
Returning (None, None) would mess with None checks since bool((None,None)) == True.

src/codemodder/codemods/utils_mixin.py Outdated Show resolved Hide resolved
src/core_codemods/harden_pyyaml.py Outdated Show resolved Hide resolved
src/core_codemods/tempfile_mktemp.py Outdated Show resolved Hide resolved
)
maybe_name = maybe_name or self._module_name
if maybe_name and maybe_name == self._module_name:
self.add_needed_import(self._module_name)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these new green lines added are the same (or almost?) in every codemod added so maybe make this a separate method to call to dedupe

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These address a very specific problem that are shared by those codemods. I don't want to add it to the api because the solution needs NameResolutionMixin which depends on ScopeProvider.

Metadata is calculated at the start of every transform on a as-need basis (libcst looks at METADATA_DEPENDENCIES for that). Integrating it to the API means every codemod would calculate the ScopeProvider metadata, making it a bit more expensive.

Maybe creating a class for those types of codemods would be a good idea, but I'd rather do that when we try to rewrite those in pure libcst.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree the duplication here is not ideal. I think we need to revisit the whole concept of utility mixins for this reason, although I understand the reasons it was done this way.

Copy link
Member

@drdavella drdavella left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM but please delete the unused pytest import.

tests/codemods/test_tempfile_mktemp.py Outdated Show resolved Hide resolved
)
maybe_name = maybe_name or self._module_name
if maybe_name and maybe_name == self._module_name:
self.add_needed_import(self._module_name)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree the duplication here is not ideal. I think we need to revisit the whole concept of utility mixins for this reason, although I understand the reasons it was done this way.

@andrecsilva andrecsilva merged commit cf2c50c into main Oct 30, 2023
11 checks passed
@andrecsilva andrecsilva deleted the pyyaml-alias branch October 30, 2023 11:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants