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

possibility to collapse only external deps to packages #26

Merged
merged 18 commits into from
Feb 1, 2024

Conversation

dg-pb
Copy link
Contributor

@dg-pb dg-pb commented Nov 15, 2023

I tried to implement it with minimal changes.

Closes #25

Would be great to have this one as I most often need to analyse internal dependency structure, while I want to see externals dependencies, but only top levels there as I generally care about dependency as a whole, which part doesn't concern me much as I inevitable depend on the whole of it.

Copy link
Owner

@mgedmin mgedmin left a comment

Choose a reason for hiding this comment

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

I like the feature. I have some reservations about the implementation. The most important bit would be unit tests; if I had a unit test, I wouldn't mind trying to figure out a nice readable algorithm implementation.

findimports.py Show resolved Hide resolved
findimports.py Outdated
@@ -97,7 +99,7 @@
from operator import attrgetter


__version__ = '2.3.1.dev0'
__version__ = '2.3.0'
Copy link
Owner

Choose a reason for hiding this comment

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

Please do not touch __version__ . As part of the release process I remove the .dev0 suffix and check for the need of semver-ish version number increases by looking at the changelog (in CHANGES.rst).

I used to preemptively increase the next upcoming version (like '2.3.1.dev0' -> '2.4.0.dev0') when I implemented a new feature, but this way it's easy to accidentally bump the minor version twice, so I mostly stopped.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That was accidental. I did work in site packages, then copied over. my bad

findimports.py Outdated
@@ -1005,6 +1019,8 @@ def main(argv=None):
args = parser.parse_args(args=argv[1:] if argv else None)
except SystemExit as e:
return e.code
if args.condense_to_packages and args.condense_to_packages_externals:
raise argparse.ArgumentError('only one of -p and -pE can be provided')
Copy link
Owner

Choose a reason for hiding this comment

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

I think this will print a traceback at the user instead of reporting an error message?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It does report the message, but there was a bug, message is 2nd arg, which is mandatory.

findimports.py Outdated
if externals_only and name in internal_names:
package_name = name
else:
package_name = self.packageOf(name, packagelevel)
Copy link
Owner

@mgedmin mgedmin Nov 15, 2023

Choose a reason for hiding this comment

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

This is a bit gnarly. I would like a couple of extra functions, maybe isExternal() and maybePackageOf(modname, packagelevel, externals_only) and then hopefully the old loop may suffice?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agree it's not ideal from design perspective, but the logic is working correctly there. Maybe leaving some notes for the next time some bigger work is done would suffice?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That appeared to be more straight forward than I initially thought. done.

findimports.py Outdated
g = g.packageGraph(args.packagelevel)
g = g.packageGraph(args.packagelevel, False)
elif args.condense_to_packages_externals:
g = g.packageGraph(args.packagelevel, True)
Copy link
Owner

Choose a reason for hiding this comment

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

Personal style rule: never pass a True/False using positional argument syntax; always use keyword argument syntax to make it clear what options this thing enables or disables.

@dg-pb
Copy link
Contributor Author

dg-pb commented Nov 15, 2023

Fixed the small ones.

Do you prefer to make some changes yourself and merge it? As you mentioned some design issues, I think you are in much better position of doing it to your liking.

Otherwise, let me know what would be satisfactory for a merge.

@mgedmin
Copy link
Owner

mgedmin commented Nov 16, 2023

Well, unit tests are a requirement. CI currently fails because test coverage fell below 100%.

I would like to experiment with the code structure myself, but I'm too lazy to test the changes manually. Having unit tests I could trust would be helpful.

@dg-pb
Copy link
Contributor Author

dg-pb commented Nov 16, 2023

Added one more option, which is to remove prefixes. This one is from pydeps.

Tests should be running now.

One more edit was to factor out dot string construction from printing it to stdout. This allows programmatic access to this feature.

For more complex dot outputs some class e.g. DotMaker would be useful. But that's maybe for the future.

findimports.py Outdated
try:
args = parser.parse_args(args=argv[1:] if argv else None)
except SystemExit as e:
return e.code
if args.condense_to_packages and args.condense_to_packages_externals:
raise argparse.ArgumentError(
None, 'only one of -p and -pE can be provided')
Copy link
Owner

Choose a reason for hiding this comment

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

This is the only statement not covered by the unit tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should be good now.

@mgedmin
Copy link
Owner

mgedmin commented Nov 17, 2023

Thank you! I will take a closer look a bit later. Please ping me if I seem to forget!

@mgedmin mgedmin changed the title possibility yo collapse only external deps to packages possibility to collapse only external deps to packages Nov 17, 2023
@dg-pb
Copy link
Contributor Author

dg-pb commented Nov 23, 2023

Made one more edit. It was still showing:
import os.path even if standard modules were off.

@dg-pb
Copy link
Contributor Author

dg-pb commented Feb 1, 2024

Added one more feature - ability to specify maximum depth of ast tree.

In my case, I sometimes want to see only top level imports as there are some irrelevant ones inside functions.

Copy link
Owner

@mgedmin mgedmin left a comment

Choose a reason for hiding this comment

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

Looks good, one comment about --rmprefix that I'd like to resolve before merging.

findimports.py Show resolved Hide resolved
findimports.py Show resolved Hide resolved
findimports.py Outdated Show resolved Hide resolved
@mgedmin mgedmin merged commit 448c9ba into mgedmin:master Feb 1, 2024
12 checks passed
@mgedmin
Copy link
Owner

mgedmin commented Feb 1, 2024

Do you want a new release? Or do you plan to create more PRs first?

@dg-pb
Copy link
Contributor Author

dg-pb commented Feb 1, 2024

New release would be great, thank you.

@mgedmin
Copy link
Owner

mgedmin commented Feb 1, 2024

Released findimports 2.4.0.

@dg-pb dg-pb deleted the collapse_externals_only branch February 1, 2024 11:55
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.

Collapse for non-package mode
2 participants